From: mohanson Date: Thu, 18 Sep 2025 03:42:30 +0000 (+0800) Subject: log/slog: optimize slog Level.String() to avoid fmt.Sprintf X-Git-Tag: go1.26rc1~823 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=8616981ce6;p=gostls13.git log/slog: optimize slog Level.String() to avoid fmt.Sprintf No more overhead of fmt.Sprintf, especially beneficial for high-frequency logging. goos: linux goarch: amd64 pkg: log/slog cpu: Intel(R) Xeon(R) Gold 6133 CPU @ 2.50GHz │ /tmp/old.txt │ /tmp/new.txt │ │ sec/op │ sec/op vs base │ LevelString-4 1006.5n ± 2% 334.2n ± 1% -66.80% (p=0.000 n=10) │ /tmp/old.txt │ /tmp/new.txt │ │ B/op │ B/op vs base │ LevelString-4 56.00 ± 0% 48.00 ± 0% -14.29% (p=0.000 n=10) │ /tmp/old.txt │ /tmp/new.txt │ │ allocs/op │ allocs/op vs base │ LevelString-4 7.000 ± 0% 7.000 ± 0% ~ (p=1.000 n=10) ¹ Change-Id: I6585d4aaa4da55d72ac70bc66dff45500eccd056 Reviewed-on: https://go-review.googlesource.com/c/go/+/704975 LUCI-TryBot-Result: Go LUCI Reviewed-by: Jonathan Amsterdam Reviewed-by: Sean Liao Reviewed-by: Emmanuel Odeke Auto-Submit: Emmanuel Odeke Reviewed-by: Michael Knyszek --- diff --git a/src/log/slog/level.go b/src/log/slog/level.go index 2957585e0e..9e812eb165 100644 --- a/src/log/slog/level.go +++ b/src/log/slog/level.go @@ -61,7 +61,11 @@ func (l Level) String() string { if val == 0 { return base } - return fmt.Sprintf("%s%+d", base, val) + sval := strconv.Itoa(int(val)) + if val > 0 { + sval = "+" + sval + } + return base + sval } switch { diff --git a/src/log/slog/level_test.go b/src/log/slog/level_test.go index 73be1126b2..c9a1c16c03 100644 --- a/src/log/slog/level_test.go +++ b/src/log/slog/level_test.go @@ -215,3 +215,25 @@ func TestLevelVarString(t *testing.T) { t.Errorf("got %q, want %q", got, want) } } + +func BenchmarkLevelString(b *testing.B) { + levels := []Level{ + 0, + LevelError, + LevelError + 2, + LevelError - 2, + LevelWarn, + LevelWarn - 1, + LevelInfo, + LevelInfo + 1, + LevelInfo - 3, + LevelDebug, + LevelDebug - 2, + } + b.ResetTimer() + for b.Loop() { + for _, level := range levels { + _ = level.String() + } + } +}