perf(stacktrace): defer shortFuncName to kept frames; drop Sprintf in frame.String#136
Conversation
… frame.String
- newStacktrace: compute shortFuncName only for frames that survive
filtering. Runtime/oops-internal frames (typically half the captured
buffer) no longer pay the string slicing + Replacer allocation.
- frame.String: direct concatenation with strconv.Itoa instead of two
reflection-based fmt.Sprintf calls; runs once per frame on every
stack trace formatting.
- getSourceFromFrame: builtin max/min instead of lo.Max/lo.Min, which
allocated a []int per call.
benchstat (darwin/arm64, Apple M3, -count=10 -cpu=1):
│ before.txt │ after.txt │
│ sec/op │ sec/op vs base │
New 2.339µ ± 2% 2.202µ ± 4% -5.84% (p=0.000 n=10)
Wrap 2.277µ ± 3% 2.122µ ± 3% -6.79% (p=0.000 n=10)
geomean 2.307µ 2.162µ -6.31%
│ before.txt │ after.txt │
│ B/op │ B/op vs base │
New 2.352Ki ± 0% 2.336Ki ± 0% -0.66% (p=0.000 n=10)
Wrap 2.336Ki ± 0% 2.320Ki ± 0% -0.67% (p=0.000 n=10)
geomean 2.344Ki 2.328Ki -0.67%
│ before.txt │ after.txt │
│ allocs/op │ allocs/op vs base │
New 15.00 ± 0% 13.00 ± 0% -13.33% (p=0.000 n=10)
Wrap 14.00 ± 0% 12.00 ± 0% -14.29% (p=0.000 n=10)
geomean 14.49 12.49 -13.81%
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #136 +/- ##
==========================================
- Coverage 90.18% 90.17% -0.02%
==========================================
Files 15 15
Lines 1233 1231 -2
==========================================
- Hits 1112 1110 -2
Misses 96 96
Partials 25 25
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR optimizes stacktrace capture and formatting in the oops package by reducing per-frame work (especially for filtered frames) and removing some allocation-heavy helpers in hot paths.
Changes:
- Defer
shortFuncNamecomputation until after frame filtering innewStacktrace. - Replace
fmt.Sprintfusage inoopsStacktraceFrame.String()with direct concatenation usingstrconv.Itoa. - Replace
lo.Max/lo.Minin source extraction with Go 1.21 builtinmax/min.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| stacktrace.go | Reduces per-frame overhead in stack capture and speeds up frame string formatting. |
| sources.go | Eliminates lo usage for min/max bounds in source context extraction to avoid per-call allocations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
newStacktrace: computeshortFuncNameonly for frames that survive filtering — runtime/oops-internal frames (typically half the captured buffer) no longer pay the string slicing +Replacerallocation.frame.String: direct string concatenation withstrconv.Itoainstead of two reflection-basedfmt.Sprintfcalls — runs once per frame on every stack trace formatting.getSourceFromFrame: builtinmax/mininstead oflo.Max/lo.Min, which allocated a[]intper call.Benchmarks
goos: darwin / goarch: arm64 / cpu: Apple M3,
-count=10 -cpu=1Test plan
go build ./...go vet ./...go test ./...