1
2
3
4
5 package benchmarks
6
7 import (
8 "context"
9 "flag"
10 "internal/race"
11 "io"
12 "log/slog"
13 "log/slog/internal"
14 "testing"
15 )
16
17 func init() {
18 flag.BoolVar(&internal.IgnorePC, "nopc", false, "do not invoke runtime.Callers")
19 }
20
21
22
23
24
25 func BenchmarkAttrs(b *testing.B) {
26 ctx := context.Background()
27 for _, handler := range []struct {
28 name string
29 h slog.Handler
30 skipRace bool
31 }{
32 {"disabled", disabledHandler{}, false},
33 {"async discard", newAsyncHandler(), true},
34 {"fastText discard", newFastTextHandler(io.Discard), false},
35 {"Text discard", slog.NewTextHandler(io.Discard, nil), false},
36 {"JSON discard", slog.NewJSONHandler(io.Discard, nil), false},
37 } {
38 logger := slog.New(handler.h)
39 b.Run(handler.name, func(b *testing.B) {
40 if handler.skipRace && race.Enabled {
41 b.Skip("skipping benchmark in race mode")
42 }
43 for _, call := range []struct {
44 name string
45 f func()
46 }{
47 {
48
49
50
51
52 "5 args",
53 func() {
54 logger.LogAttrs(nil, slog.LevelInfo, testMessage,
55 slog.String("string", testString),
56 slog.Int("status", testInt),
57 slog.Duration("duration", testDuration),
58 slog.Time("time", testTime),
59 slog.Any("error", testError),
60 )
61 },
62 },
63 {
64 "5 args ctx",
65 func() {
66 logger.LogAttrs(ctx, slog.LevelInfo, testMessage,
67 slog.String("string", testString),
68 slog.Int("status", testInt),
69 slog.Duration("duration", testDuration),
70 slog.Time("time", testTime),
71 slog.Any("error", testError),
72 )
73 },
74 },
75 {
76 "10 args",
77 func() {
78 logger.LogAttrs(nil, slog.LevelInfo, testMessage,
79 slog.String("string", testString),
80 slog.Int("status", testInt),
81 slog.Duration("duration", testDuration),
82 slog.Time("time", testTime),
83 slog.Any("error", testError),
84 slog.String("string", testString),
85 slog.Int("status", testInt),
86 slog.Duration("duration", testDuration),
87 slog.Time("time", testTime),
88 slog.Any("error", testError),
89 )
90 },
91 },
92 {
93
94 "40 args",
95 func() {
96 logger.LogAttrs(nil, slog.LevelInfo, testMessage,
97 slog.String("string", testString),
98 slog.Int("status", testInt),
99 slog.Duration("duration", testDuration),
100 slog.Time("time", testTime),
101 slog.Any("error", testError),
102 slog.String("string", testString),
103 slog.Int("status", testInt),
104 slog.Duration("duration", testDuration),
105 slog.Time("time", testTime),
106 slog.Any("error", testError),
107 slog.String("string", testString),
108 slog.Int("status", testInt),
109 slog.Duration("duration", testDuration),
110 slog.Time("time", testTime),
111 slog.Any("error", testError),
112 slog.String("string", testString),
113 slog.Int("status", testInt),
114 slog.Duration("duration", testDuration),
115 slog.Time("time", testTime),
116 slog.Any("error", testError),
117 slog.String("string", testString),
118 slog.Int("status", testInt),
119 slog.Duration("duration", testDuration),
120 slog.Time("time", testTime),
121 slog.Any("error", testError),
122 slog.String("string", testString),
123 slog.Int("status", testInt),
124 slog.Duration("duration", testDuration),
125 slog.Time("time", testTime),
126 slog.Any("error", testError),
127 slog.String("string", testString),
128 slog.Int("status", testInt),
129 slog.Duration("duration", testDuration),
130 slog.Time("time", testTime),
131 slog.Any("error", testError),
132 slog.String("string", testString),
133 slog.Int("status", testInt),
134 slog.Duration("duration", testDuration),
135 slog.Time("time", testTime),
136 slog.Any("error", testError),
137 )
138 },
139 },
140 } {
141 b.Run(call.name, func(b *testing.B) {
142 b.ReportAllocs()
143 b.RunParallel(func(pb *testing.PB) {
144 for pb.Next() {
145 call.f()
146 }
147 })
148 })
149 }
150 })
151 }
152 }
153
View as plain text