Bläddra i källkod

cache frozenConfig

Tao Wen 7 år sedan
förälder
incheckning
ee8cfb7547

+ 25 - 0
benchmarks/encode_string_test.go

@@ -0,0 +1,25 @@
+package test
+
+import (
+	"testing"
+	"github.com/json-iterator/go"
+	"bytes"
+)
+
+func Benchmark_encode_string_with_SetEscapeHTML(b *testing.B) {
+	type V struct {
+		S string
+		B bool
+		I int
+	}
+	var json = jsoniter.ConfigCompatibleWithStandardLibrary
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		buf := &bytes.Buffer{}
+		enc := json.NewEncoder(buf)
+		enc.SetEscapeHTML(true)
+		if err := enc.Encode(V{S: "s", B: true, I: 233}); err != nil {
+			b.Fatal(err)
+		}
+	}
+}

+ 13 - 9
feature_config.go

@@ -60,8 +60,11 @@ var ConfigFastest = Config{
 
 // Froze forge API from config
 func (cfg Config) Froze() API {
-	// TODO: cache frozen config
-	frozenConfig := &frozenConfig{
+	api := getFrozenConfigFromCache(cfg)
+	if api != nil {
+		return api
+	}
+	api = &frozenConfig{
 		sortMapKeys:                   cfg.SortMapKeys,
 		indentionStep:                 cfg.IndentionStep,
 		objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString,
@@ -69,21 +72,22 @@ func (cfg Config) Froze() API {
 		streamPool:                    make(chan *Stream, 16),
 		iteratorPool:                  make(chan *Iterator, 16),
 	}
-	frozenConfig.initCache()
+	api.initCache()
 	if cfg.MarshalFloatWith6Digits {
-		frozenConfig.marshalFloatWith6Digits()
+		api.marshalFloatWith6Digits()
 	}
 	if cfg.EscapeHTML {
-		frozenConfig.escapeHTML()
+		api.escapeHTML()
 	}
 	if cfg.UseNumber {
-		frozenConfig.useNumber()
+		api.useNumber()
 	}
 	if cfg.ValidateJsonRawMessage {
-		frozenConfig.validateJsonRawMessage()
+		api.validateJsonRawMessage()
 	}
-	frozenConfig.configBeforeFrozen = cfg
-	return frozenConfig
+	api.configBeforeFrozen = cfg
+	addFrozenConfigToCache(cfg, api)
+	return api
 }
 
 func (cfg *frozenConfig) validateJsonRawMessage() {

+ 14 - 0
feature_config_with_sync_map.go

@@ -48,4 +48,18 @@ func (cfg *frozenConfig) getEncoderFromCache(cacheKey reflect.Type) ValEncoder {
 		return encoder.(ValEncoder)
 	}
 	return nil
+}
+
+var cfgCache = &sync.Map{}
+
+func getFrozenConfigFromCache(cfg Config) *frozenConfig {
+	obj, found := cfgCache.Load(cfg)
+	if found {
+		return obj.(*frozenConfig)
+	}
+	return nil
+}
+
+func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) {
+	cfgCache.Store(cfg, frozenConfig)
 }

+ 16 - 0
feature_config_without_sync_map.go

@@ -52,3 +52,19 @@ func (cfg *frozenConfig) getEncoderFromCache(cacheKey reflect.Type) ValEncoder {
 	cfg.cacheLock.RUnlock()
 	return encoder
 }
+
+var cfgCacheLock = &sync.RWMutex{}
+var cfgCache = map[Config]*frozenConfig{}
+
+func getFrozenConfigFromCache(cfg Config) *frozenConfig {
+	cfgCacheLock.RLock()
+	frozenConfig := cfgCache[cfg]
+	cfgCacheLock.RUnlock()
+	return frozenConfig
+}
+
+func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) {
+	cfgCacheLock.Lock()
+	cfgCache[cfg] = frozenConfig
+	cfgCacheLock.Unlock()
+}