From 44dc4f000e0ad6c3c53c4678081507ceec6cb64e Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Sun, 23 Oct 2016 13:15:47 +0900 Subject: [PATCH] New caching mechanism --- main.go | 52 +++++++++++++++++++++++++++++++++++++--------------- main_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 15 deletions(-) create mode 100644 main_test.go diff --git a/main.go b/main.go index 0d3bbcb7..8002204a 100644 --- a/main.go +++ b/main.go @@ -1,17 +1,21 @@ package main import ( + "encoding/json" "fmt" "io" "io/ioutil" "runtime" "strconv" "strings" + "time" "github.com/Joker/jade" + "github.com/OneOfOne/xxhash" "github.com/aerojs/aero" "github.com/blitzprog/arn" "github.com/buaazp/fasthttprouter" + cache "github.com/patrickmn/go-cache" "github.com/robertkrimen/otto" "github.com/valyala/fasthttp" "github.com/valyala/fasttemplate" @@ -26,20 +30,44 @@ const ( hello = "Hello World" ) +var jsonToResponse *cache.Cache + func worker(script *otto.Script, jobs <-chan map[string]interface{}, results chan<- string) { vm := otto.New() for properties := range jobs { - for key, value := range properties { - vm.Set(key, value) + h := xxhash.NewS64(0) + + for _, value := range properties { + jsonBytes, err := json.Marshal(value) + + if err == nil { + h.Write(jsonBytes) + // fmt.Println(string(buffer)) + } + } + + hash := strconv.FormatUint(h.Sum64(), 10) + cachedResponse, found := jsonToResponse.Get(hash) + + if found { + results <- cachedResponse.(string) + } else { + for key, value := range properties { + vm.Set(key, value) + } + + result, _ := vm.Run(script) + code, _ := result.ToString() + results <- code + + jsonToResponse.Set(hash, code, cache.DefaultExpiration) } - result, _ := vm.Run(script) - code, _ := result.ToString() - results <- code } } func main() { + jsonToResponse = cache.New(5*time.Minute, 1*time.Minute) app := aero.New() jade.PrettyOutput = false code, _ := jade.ParseFile("pages/anime/anime.pug") @@ -103,20 +131,14 @@ func main() { return } - myMap := make(map[string]interface{}) - myMap["anime"] = anime - jobs <- myMap + templateParams := make(map[string]interface{}) + templateParams["anime"] = anime + jobs <- templateParams aero.Respond(ctx, <-results) - - // if runErr != nil { - // panic(runErr) - // } - - // aero.Respond(ctx, result.String()) }) - fmt.Println("Starting server on http://localhost:5000/") + fmt.Println("Starting server on http://localhost:4000/") app.Run() } diff --git a/main_test.go b/main_test.go new file mode 100644 index 00000000..c2a22d43 --- /dev/null +++ b/main_test.go @@ -0,0 +1,33 @@ +package main + +import ( + "testing" + "unsafe" +) + +var code = "Hello World" +var slice = []byte("Hello World 2") + +func BenchmarkStringToBytesSafe(b *testing.B) { + for i := 0; i < b.N; i++ { + slice = []byte(code) + } +} + +func BenchmarkStringToBytesUnsafe(b *testing.B) { + for i := 0; i < b.N; i++ { + slice = *(*[]byte)(unsafe.Pointer(&code)) + } +} + +func BenchmarkBytesToStringSafe(b *testing.B) { + for i := 0; i < b.N; i++ { + code = string(slice) + } +} + +func BenchmarkBytesToStringUnsafe(b *testing.B) { + for i := 0; i < b.N; i++ { + code = *(*string)(unsafe.Pointer(&slice)) + } +}