From 64bf9904edd19577347c12a04eb0b9f7e097f2b6 Mon Sep 17 00:00:00 2001 From: Pawel Krolikowski Date: Sat, 22 Jul 2023 23:13:50 -0400 Subject: [PATCH] WIP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ❯ go test -bench BenchmarkAnyInGoroutine -benchmem -run Any -test.cpuprofile ~/cpuprof goos: darwin goarch: arm64 pkg: go.uber.org/zap BenchmarkAnyInGoroutine1/int-in-goroutine-with-stack-12 3125690 376.5 ns/op 88 B/op 2 allocs/op BenchmarkAnyInGoroutine1/any-in-goroutine-with-stack-12 1763952 665.0 ns/op 88 B/op 2 allocs/op BenchmarkAnyInGoroutine1/any-int-in-goroutine-with-stack-12 2904816 398.3 ns/op 88 B/op 2 allocs/op BenchmarkAnyInGoroutine1/any-12 4141492 289.2 ns/op 64 B/op 1 allocs/op BenchmarkAnyInGoroutine1/int-12 4395013 274.5 ns/op 64 B/op 1 allocs/op BenchmarkAnyInGoroutine1/goroutine-12 5005946 217.9 ns/op 0 B/op 0 allocs/op BenchmarkAnyInGoroutine1/int-in-goroutine-12 2079958 594.9 ns/op 88 B/op 2 allocs/op BenchmarkAnyInGoroutine1/any-in-goroutine-12 1773802 649.9 ns/op 88 B/op 2 allocs/op --- field.go | 10 ++++ logger_bench_test.go | 110 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/field.go b/field.go index bbb745db5..ca36069d8 100644 --- a/field.go +++ b/field.go @@ -547,3 +547,13 @@ func Any(key string, value interface{}) Field { return Reflect(key, val) } } + +// AnyInt is a dummified version of Any that can handle ints. +func AnyInt(key string, value interface{}) Field { + switch val := value.(type) { + case int: + return Int(key, val) + default: + return Reflect(key, val) + } +} diff --git a/logger_bench_test.go b/logger_bench_test.go index 41e661577..74a22c437 100644 --- a/logger_bench_test.go +++ b/logger_bench_test.go @@ -22,6 +22,7 @@ package zap import ( "errors" + "sync" "testing" "time" @@ -238,3 +239,112 @@ func Benchmark100Fields(b *testing.B) { logger.With(first...).Info("Child loggers with lots of context.", second...) } } + +func dummy(wg *sync.WaitGroup, s string, i int) string { + if i == 0 { + wg.Wait() + return "1" + s + } + return dummy(wg, s, i-1) +} + +func stackGrower(n int) *sync.WaitGroup { + wg := sync.WaitGroup{} + wg.Add(1) + + go dummy(&wg, "hi", n) + return &wg +} + +func BenchmarkAnyInGoroutine1(b *testing.B) { + logger := New( + zapcore.NewCore( + zapcore.NewJSONEncoder(NewProductionConfig().EncoderConfig), + &ztest.Discarder{}, + DebugLevel, + ), + ) + + b.Run("int-in-goroutine-with-stack", func(b *testing.B) { + wg := sync.WaitGroup{} + wg.Add(b.N) + defer stackGrower(1000).Done() + b.ResetTimer() + for i := 0; i < b.N; i++ { + go func() { + logger.Info("", Int("one", 1)) + wg.Done() + }() + } + wg.Wait() + b.StopTimer() + }) + b.Run("any-in-goroutine-with-stack", func(b *testing.B) { + wg := sync.WaitGroup{} + wg.Add(b.N) + defer stackGrower(1000).Done() + b.ResetTimer() + for i := 0; i < b.N; i++ { + go func() { + logger.Info("", Any("one", 1)) + wg.Done() + }() + } + wg.Wait() + b.StopTimer() + }) + b.Run("any-int-in-goroutine-with-stack", func(b *testing.B) { + wg := sync.WaitGroup{} + wg.Add(b.N) + defer stackGrower(1000).Done() + b.ResetTimer() + for i := 0; i < b.N; i++ { + go func() { + logger.Info("", AnyInt("one", 1)) + wg.Done() + }() + } + wg.Wait() + b.StopTimer() + }) + b.Run("any", func(b *testing.B) { + for i := 0; i < b.N; i++ { + logger.Info("", Any("one", 1)) + } + }) + b.Run("int", func(b *testing.B) { + for i := 0; i < b.N; i++ { + logger.Info("", Int("one", 1)) + } + }) + b.Run("goroutine", func(b *testing.B) { + for i := 0; i < b.N; i++ { + go func() {}() + } + }) + b.Run("int-in-goroutine", func(b *testing.B) { + wg := sync.WaitGroup{} + wg.Add(b.N) + b.ResetTimer() + for i := 0; i < b.N; i++ { + go func() { + logger.Info("", Int("one", 1)) + wg.Done() + }() + } + wg.Wait() + }) + b.Run("any-in-goroutine", func(b *testing.B) { + wg := sync.WaitGroup{} + wg.Add(b.N) + b.ResetTimer() + for i := 0; i < b.N; i++ { + go func() { + logger.Info("", Any("one", 1)) + wg.Done() + }() + } + wg.Wait() + b.StopTimer() + }) +}