Description
At the moment, https://pkg.go.dev/golang.org/x/exp/slog passes Logger
around by pointer. The implication is that functions like Logger.With
need one additional allocation, for the new Logger
instance.
The alternative is to pass it as value, like go-logr does. This improves performance for With
(see https://github.com/golang/exp/compare/master...pohly:exp:logger-as-value?expand=1) and others (not tested yet):
name old time/op new time/op delta
With/Text_discard/no_parameters-36 165ns ±18% 135ns ±25% ~ (p=0.222 n=5+5)
With/Text_discard/1_key/value_pair-36 397ns ± 2% 356ns ± 1% -10.39% (p=0.008 n=5+5)
With/Text_discard/5_key/value_pairs-36 1.64µs ± 1% 1.54µs ± 1% -6.26% (p=0.008 n=5+5)
With/JSON_discard/no_parameters-36 210ns ± 4% 175ns ± 5% -16.38% (p=0.008 n=5+5)
With/JSON_discard/1_key/value_pair-36 435ns ± 1% 404ns ± 3% -7.02% (p=0.008 n=5+5)
With/JSON_discard/5_key/value_pairs-36 2.03µs ± 1% 1.97µs ± 1% -3.06% (p=0.008 n=5+5)
name old alloc/op new alloc/op delta
With/Text_discard/no_parameters-36 169B ± 0% 153B ± 0% -9.47% (p=0.008 n=5+5)
With/Text_discard/1_key/value_pair-36 290B ± 0% 274B ± 0% ~ (p=0.079 n=4+5)
With/Text_discard/5_key/value_pairs-36 1.00kB ± 0% 0.98kB ± 0% -1.70% (p=0.008 n=5+5)
With/JSON_discard/no_parameters-36 169B ± 0% 153B ± 0% -9.47% (p=0.008 n=5+5)
With/JSON_discard/1_key/value_pair-36 307B ± 0% 290B ± 0% -5.54% (p=0.008 n=5+5)
With/JSON_discard/5_key/value_pairs-36 1.26kB ± 0% 1.24kB ± 0% -1.35% (p=0.008 n=5+5)
name old allocs/op new allocs/op delta
With/Text_discard/no_parameters-36 3.00 ± 0% 2.00 ± 0% -33.33% (p=0.008 n=5+5)
With/Text_discard/1_key/value_pair-36 6.00 ± 0% 5.00 ± 0% -16.67% (p=0.008 n=5+5)
With/Text_discard/5_key/value_pairs-36 12.0 ± 0% 11.0 ± 0% -8.33% (p=0.008 n=5+5)
With/JSON_discard/no_parameters-36 3.00 ± 0% 2.00 ± 0% -33.33% (p=0.008 n=5+5)
With/JSON_discard/1_key/value_pair-36 7.00 ± 0% 6.00 ± 0% -14.29% (p=0.008 n=5+5)
With/JSON_discard/5_key/value_pairs-36 12.0 ± 0% 11.0 ± 0% -8.33% (p=0.008 n=5+5)
The downside is that the size of Logger
should not grow indefinitely in the future. But that is true anyway (because these calls must clone it) and also seems unlikely.
Related to this is the question whether calling any of the methods for the null Logger
should be valid. Currently they panic because Logger.handler
will be nil. I think this is the right choice given that they are performance-sensitive, but I wanted to ask anyway...