-
Notifications
You must be signed in to change notification settings - Fork 24
perf: human log sink performance bump via reduction of allocs/total allocated memory #220
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Callum Styan <callumstyan@gmail.com>
Signed-off-by: Callum Styan <callumstyan@gmail.com>
…e the optimized version should return an error Signed-off-by: Callum Styan <callumstyan@gmail.com>
Pull Request Test Coverage Report for Build 3cb927f1a22a74cedce94eeec74e36f7dad4396e-PR-220Details
💛 - Coveralls |
Signed-off-by: Callum Styan <callumstyan@gmail.com>
Signed-off-by: Callum Styan <callumstyan@gmail.com>
…ne very specific case that should never happen if we're actually going to OOM via logging it would panic Signed-off-by: Callum Styan <callumstyan@gmail.com>
… files for new test cases Signed-off-by: Callum Styan <callumstyan@gmail.com>
Signed-off-by: Callum Styan <callumstyan@gmail.com>
| level := ent.Level.String() | ||
| level = strings.ToLower(level) | ||
| if len(level) > 4 { | ||
| level = level[:4] | ||
| } | ||
| level = "[" + level + "]" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wow this old code was kinda dumb in comparison.
| func bracketedLevel(l slog.Level) string { | ||
| switch l { | ||
| case slog.LevelDebug: | ||
| return "[debu]" | ||
| case slog.LevelInfo: | ||
| return "[info]" | ||
| case slog.LevelWarn: | ||
| return "[warn]" | ||
| case slog.LevelError: | ||
| return "[erro]" | ||
| case slog.LevelCritical: | ||
| return "[crit]" | ||
| case slog.LevelFatal: | ||
| return "[fata]" | ||
| default: | ||
| return "[unkn]" | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
|
|
||
| // signed ints | ||
| case int: | ||
| var a [20]byte |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the 20 arbitrary? Can it be less? Or can it be overflowed with very large numbers?
Strings are not handled in this switch statement. Is it because strings are of arbitrary length? Can we handle them quicker than the formatValue? I ask because I imagine most of our types logged are strings.
Note, zerolog handles this by making the typed constructors. Instead of a generic slog.F("", <any>), they do slog.Int32/String/Float64/etc("", <typed>).
| @@ -0,0 +1,241 @@ | |||
| diff --git a/internal/entryhuman/entry.go b/internal/entryhuman/entry.go | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this file here?
I was poking around in profiling data for our dogfood instance and I noticed that over a 24h period debug logging through the human readable log sink was producing 10-12% of our memory allocation. Garbage collection is only ~7.5% of our CPU time, but hopefully this has a nice reduction for allocs/memory allocated and small reduction for GC related CPU usage.
Benchmark data:
Note that the existing benchmark didn't cover many use cases, so the changes are not as obvious there:
Current alloc space:

Current alloc object:

Alloc objects path:

Alloc space path:

GC CPU time:
