github.com/v2fly/tools@v0.100.0/internal/event/bench_test.go (about) 1 // Copyright 2020 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package event_test 6 7 import ( 8 "context" 9 "io/ioutil" 10 "log" 11 "testing" 12 13 "github.com/v2fly/tools/internal/event" 14 "github.com/v2fly/tools/internal/event/core" 15 "github.com/v2fly/tools/internal/event/export" 16 "github.com/v2fly/tools/internal/event/keys" 17 "github.com/v2fly/tools/internal/event/label" 18 ) 19 20 type Hooks struct { 21 A func(ctx context.Context, a int) (context.Context, func()) 22 B func(ctx context.Context, b string) (context.Context, func()) 23 } 24 25 var ( 26 aValue = keys.NewInt("a", "") 27 bValue = keys.NewString("b", "") 28 aCount = keys.NewInt64("aCount", "Count of time A is called.") 29 aStat = keys.NewInt("aValue", "A value.") 30 bCount = keys.NewInt64("B", "Count of time B is called.") 31 bLength = keys.NewInt("BLen", "B length.") 32 33 Baseline = Hooks{ 34 A: func(ctx context.Context, a int) (context.Context, func()) { 35 return ctx, func() {} 36 }, 37 B: func(ctx context.Context, b string) (context.Context, func()) { 38 return ctx, func() {} 39 }, 40 } 41 42 StdLog = Hooks{ 43 A: func(ctx context.Context, a int) (context.Context, func()) { 44 log.Printf("A where a=%d", a) 45 return ctx, func() {} 46 }, 47 B: func(ctx context.Context, b string) (context.Context, func()) { 48 log.Printf("B where b=%q", b) 49 return ctx, func() {} 50 }, 51 } 52 53 Log = Hooks{ 54 A: func(ctx context.Context, a int) (context.Context, func()) { 55 core.Log1(ctx, "A", aValue.Of(a)) 56 return ctx, func() {} 57 }, 58 B: func(ctx context.Context, b string) (context.Context, func()) { 59 core.Log1(ctx, "B", bValue.Of(b)) 60 return ctx, func() {} 61 }, 62 } 63 64 Trace = Hooks{ 65 A: func(ctx context.Context, a int) (context.Context, func()) { 66 return core.Start1(ctx, "A", aValue.Of(a)) 67 }, 68 B: func(ctx context.Context, b string) (context.Context, func()) { 69 return core.Start1(ctx, "B", bValue.Of(b)) 70 }, 71 } 72 73 Stats = Hooks{ 74 A: func(ctx context.Context, a int) (context.Context, func()) { 75 core.Metric1(ctx, aStat.Of(a)) 76 core.Metric1(ctx, aCount.Of(1)) 77 return ctx, func() {} 78 }, 79 B: func(ctx context.Context, b string) (context.Context, func()) { 80 core.Metric1(ctx, bLength.Of(len(b))) 81 core.Metric1(ctx, bCount.Of(1)) 82 return ctx, func() {} 83 }, 84 } 85 86 initialList = []int{0, 1, 22, 333, 4444, 55555, 666666, 7777777} 87 stringList = []string{ 88 "A value", 89 "Some other value", 90 "A nice longer value but not too long", 91 "V", 92 "", 93 "ı", 94 "prime count of values", 95 } 96 ) 97 98 type namedBenchmark struct { 99 name string 100 test func(*testing.B) 101 } 102 103 func Benchmark(b *testing.B) { 104 b.Run("Baseline", Baseline.runBenchmark) 105 b.Run("StdLog", StdLog.runBenchmark) 106 benchmarks := []namedBenchmark{ 107 {"Log", Log.runBenchmark}, 108 {"Trace", Trace.runBenchmark}, 109 {"Stats", Stats.runBenchmark}, 110 } 111 112 event.SetExporter(nil) 113 for _, t := range benchmarks { 114 b.Run(t.name+"NoExporter", t.test) 115 } 116 117 event.SetExporter(noopExporter) 118 for _, t := range benchmarks { 119 b.Run(t.name+"Noop", t.test) 120 } 121 122 event.SetExporter(export.Spans(export.LogWriter(ioutil.Discard, false))) 123 for _, t := range benchmarks { 124 b.Run(t.name, t.test) 125 } 126 } 127 128 func A(ctx context.Context, hooks Hooks, a int) int { 129 ctx, done := hooks.A(ctx, a) 130 defer done() 131 return B(ctx, hooks, a, stringList[a%len(stringList)]) 132 } 133 134 func B(ctx context.Context, hooks Hooks, a int, b string) int { 135 _, done := hooks.B(ctx, b) 136 defer done() 137 return a + len(b) 138 } 139 140 func (hooks Hooks) runBenchmark(b *testing.B) { 141 ctx := context.Background() 142 b.ReportAllocs() 143 b.ResetTimer() 144 var acc int 145 for i := 0; i < b.N; i++ { 146 for _, value := range initialList { 147 acc += A(ctx, hooks, value) 148 } 149 } 150 } 151 152 func init() { 153 log.SetOutput(ioutil.Discard) 154 } 155 156 func noopExporter(ctx context.Context, ev core.Event, lm label.Map) context.Context { 157 return ctx 158 }