package configx import ( "fmt" "io/ioutil" "os" "path" "testing" "github.com/spf13/pflag" "github.com/dgraph-io/ristretto" "github.com/stretchr/testify/require" ) func newKoanf(schemaPath string, configPaths []string, modifiers ...OptionModifier) (*Provider, error) { schema, err := ioutil.ReadFile(schemaPath) if err != nil { return nil, err } f := pflag.NewFlagSet("config", pflag.ContinueOnError) f.StringSliceP("config", "c", configPaths, "") modifiers = append(modifiers, WithFlags(f)) k, err := New(schema, modifiers...) if err != nil { return nil, err } return k, nil } func setEnvs(t testing.TB, envs [][2]string) { for _, v := range envs { require.NoError(t, os.Setenv(v[0], v[1])) } t.Cleanup(func() { for _, v := range envs { _ = os.Unsetenv(v[0]) } }) } func BenchmarkKoanf(b *testing.B) { setEnvs(b, [][2]string{{"MUTATORS_HEADER_ENABLED", "true"}}) schemaPath := path.Join("stub/benchmark/schema.config.json") k, err := newKoanf(schemaPath, []string{"stub/benchmark/benchmark.yaml"}) require.NoError(b, err) keys := k.Koanf.Keys() numKeys := len(keys) b.Run("cache=false", func(b *testing.B) { var key string b.ResetTimer() for i := 0; i < b.N; i++ { key = keys[i%numKeys] if k.Koanf.Get(key) == nil { b.Fatalf("cachedFind returned a nil value for key: %s", key) } } }) b.Run("cache=true", func(b *testing.B) { for i, c := range []*ristretto.Config{ { NumCounters: int64(numKeys), MaxCost: 500000, BufferItems: 64, }, { NumCounters: int64(numKeys * 10), MaxCost: 1000000, BufferItems: 64, }, { NumCounters: int64(numKeys * 10), MaxCost: 5000000, BufferItems: 64, }, } { cache, err := ristretto.NewCache(c) require.NoError(b, err) b.Run(fmt.Sprintf("config=%d", i), func(b *testing.B) { var key string var found bool var val interface{} b.ResetTimer() for i := 0; i < b.N; i++ { key = keys[i%numKeys] if val, found = cache.Get(key); !found { val = k.Koanf.Get(key) _ = cache.Set(key, val, 0) } if val == nil { b.Fatalf("cachedFind returned a nil value for key: %s", key) } } }) } }) }