mirror of
https://github.com/golang/go
synced 2024-11-05 22:56:11 -07:00
36db529775
This adds variants of the main event functions that take specific numbers of tags, rather than a tag slice. This reduces the allocation cost when using those functions with no exporter to zero. name old time/op new time/op delta /Baseline-8 158ns ± 7% 154ns ± 1% ~ /StdLog-8 6.90µs ± 1% 6.83µs ± 1% ~ /LogNoExporter-8 1.78µs ± 5% 1.20µs ± 3% -32.37% /TraceNoExporter-8 3.11µs ± 3% 2.48µs ± 2% -20.39% /StatsNoExporter-8 3.18µs ± 5% 1.87µs ± 3% -41.16% /Log-8 46.8µs ± 2% 44.8µs ± 1% -4.33% /Trace-8 55.1µs ± 5% 54.3µs ± 3% ~ /Stats-8 15.8µs ± 3% 13.4µs ± 1% -15.00% name old alloc/op new alloc/op delta /Baseline-8 0.00B 0.00B ~ /StdLog-8 552B ± 0% 552B ± 0% ~ /LogNoExporter-8 1.02kB ± 0% 0.00kB -100.00% /TraceNoExporter-8 1.54kB ± 0% 0.51kB ± 0% -66.67% /StatsNoExporter-8 2.05kB ± 0% 0.00kB -100.00% /Log-8 26.0kB ± 0% 24.0kB ± 0% -7.87% /Trace-8 28.7kB ± 0% 27.1kB ± 0% ~ /Stats-8 13.3kB ± 0% 10.2kB ± 0% -23.08% name old allocs/op new allocs/op delta /Baseline-8 0.00 0.00 ~ /StdLog-8 30.0 ± 0% 30.0 ± 0% ~ /LogNoExporter-8 16.0 ± 0% 0.0 -100.00% /TraceNoExporter-8 32.0 ± 0% 16.0 ± 0% -50.00% /StatsNoExporter-8 32.0 ± 0% 0.0 -100.00% /Log-8 430 ± 0% 382 ± 0% -11.16% /Trace-8 496 ± 0% 464 ± 0% -6.45% /Stats-8 192 ± 0% 128 ± 0% -33.33% Change-Id: I629c0d506ab07de6f12b0acbecfc7407f59a4285 Reviewed-on: https://go-review.googlesource.com/c/tools/+/225580 Run-TryBot: Ian Cottrell <iancottrell@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com> Reviewed-by: Robert Findley <rfindley@google.com>
150 lines
3.4 KiB
Go
150 lines
3.4 KiB
Go
package telemetry_test
|
||
|
||
import (
|
||
"context"
|
||
"log"
|
||
"testing"
|
||
|
||
"golang.org/x/tools/internal/telemetry/event"
|
||
"golang.org/x/tools/internal/telemetry/export"
|
||
)
|
||
|
||
type Hooks struct {
|
||
A func(ctx context.Context, a int) (context.Context, func())
|
||
B func(ctx context.Context, b string) (context.Context, func())
|
||
}
|
||
|
||
var (
|
||
aValue = event.NewIntKey("a", "")
|
||
bValue = event.NewStringKey("b", "")
|
||
aCount = event.NewInt64Key("aCount", "Count of time A is called.")
|
||
aStat = event.NewIntKey("aValue", "A value.")
|
||
bCount = event.NewInt64Key("B", "Count of time B is called.")
|
||
bLength = event.NewIntKey("BLen", "B length.")
|
||
|
||
Baseline = Hooks{
|
||
A: func(ctx context.Context, a int) (context.Context, func()) {
|
||
return ctx, func() {}
|
||
},
|
||
B: func(ctx context.Context, b string) (context.Context, func()) {
|
||
return ctx, func() {}
|
||
},
|
||
}
|
||
|
||
StdLog = Hooks{
|
||
A: func(ctx context.Context, a int) (context.Context, func()) {
|
||
log.Printf("A where a=%d", a)
|
||
return ctx, func() {}
|
||
},
|
||
B: func(ctx context.Context, b string) (context.Context, func()) {
|
||
log.Printf("B where b=%q", b)
|
||
return ctx, func() {}
|
||
},
|
||
}
|
||
|
||
Log = Hooks{
|
||
A: func(ctx context.Context, a int) (context.Context, func()) {
|
||
event.Print1(ctx, "A", aValue.Of(a))
|
||
return ctx, func() {}
|
||
},
|
||
B: func(ctx context.Context, b string) (context.Context, func()) {
|
||
event.Print1(ctx, "B", bValue.Of(b))
|
||
return ctx, func() {}
|
||
},
|
||
}
|
||
|
||
Trace = Hooks{
|
||
A: func(ctx context.Context, a int) (context.Context, func()) {
|
||
return event.StartSpan1(ctx, "A", aValue.Of(a))
|
||
},
|
||
B: func(ctx context.Context, b string) (context.Context, func()) {
|
||
return event.StartSpan1(ctx, "B", bValue.Of(b))
|
||
},
|
||
}
|
||
|
||
Stats = Hooks{
|
||
A: func(ctx context.Context, a int) (context.Context, func()) {
|
||
event.Record1(ctx, aStat.Of(a))
|
||
event.Record1(ctx, aCount.Of(1))
|
||
return ctx, func() {}
|
||
},
|
||
B: func(ctx context.Context, b string) (context.Context, func()) {
|
||
event.Record1(ctx, bLength.Of(len(b)))
|
||
event.Record1(ctx, bCount.Of(1))
|
||
return ctx, func() {}
|
||
},
|
||
}
|
||
|
||
initialList = []int{0, 1, 22, 333, 4444, 55555, 666666, 7777777}
|
||
stringList = []string{
|
||
"A value",
|
||
"Some other value",
|
||
"A nice longer value but not too long",
|
||
"V",
|
||
"",
|
||
"ı",
|
||
"prime count of values",
|
||
}
|
||
)
|
||
|
||
type namedBenchmark struct {
|
||
name string
|
||
test func(*testing.B)
|
||
}
|
||
|
||
func Benchmark(b *testing.B) {
|
||
b.Run("Baseline", Baseline.runBenchmark)
|
||
b.Run("StdLog", StdLog.runBenchmark)
|
||
benchmarks := []namedBenchmark{
|
||
{"Log", Log.runBenchmark},
|
||
{"Trace", Trace.runBenchmark},
|
||
{"Stats", Stats.runBenchmark},
|
||
}
|
||
|
||
event.SetExporter(nil)
|
||
for _, t := range benchmarks {
|
||
b.Run(t.name+"NoExporter", t.test)
|
||
}
|
||
|
||
event.SetExporter(noopExporter)
|
||
for _, t := range benchmarks {
|
||
b.Run(t.name, t.test)
|
||
}
|
||
}
|
||
|
||
func A(ctx context.Context, hooks Hooks, a int) int {
|
||
ctx, done := hooks.A(ctx, a)
|
||
defer done()
|
||
return B(ctx, hooks, a, stringList[a%len(stringList)])
|
||
}
|
||
|
||
func B(ctx context.Context, hooks Hooks, a int, b string) int {
|
||
_, done := hooks.B(ctx, b)
|
||
defer done()
|
||
return a + len(b)
|
||
}
|
||
|
||
func (hooks Hooks) runBenchmark(b *testing.B) {
|
||
ctx := context.Background()
|
||
b.ReportAllocs()
|
||
b.ResetTimer()
|
||
var acc int
|
||
for i := 0; i < b.N; i++ {
|
||
for _, value := range initialList {
|
||
acc += A(ctx, hooks, value)
|
||
}
|
||
}
|
||
}
|
||
|
||
func init() {
|
||
log.SetOutput(new(noopWriter))
|
||
}
|
||
|
||
type noopWriter int
|
||
|
||
func (nw *noopWriter) Write(b []byte) (int, error) {
|
||
return len(b), nil
|
||
}
|
||
|
||
var noopExporter = export.Spans(export.LogWriter(new(noopWriter), false))
|