This repository was archived by the owner on Dec 1, 2021. It is now read-only.

Description
Hello, I'm not sure how this project would feel about a performance inspired change but figured I would at least present my findings since the gains are pretty significant. I was curious what was causing so many allocations when a specific code path failed, around 150 or so total and found the culprit to be in the stack trace printing. By adding a format function with a signature of func(b *strutil.Builder, s fmt.State, verb rune) I was able to lower it down to 7 by iterating the stack first for a good length estimate and calling Grow. The exact numbers:
BenchmarkStackObtain/er/lazy-24 500000 3035 ns/op 288 B/op 1 allocs/op
BenchmarkStackObtain/pkg/errors-24 500000 3412 ns/op 320 B/op 3 allocs/op
BenchmarkStackPrint/1_Times/er/lazy-24 100000 24778 ns/op 7244 B/op 7 allocs/op
BenchmarkStackPrint/1_Times/pkg/errors-24 30000 56817 ns/op 4057 B/op 130 allocs/op
BenchmarkStackPrint/6_Times/er/lazy-24 10000 129898 ns/op 42020 B/op 37 allocs/op
BenchmarkStackPrint/6_Times/pkg/errors-24 5000 323686 ns/op 22739 B/op 765 allocs/op
Of course printing 6 stack traces will never happen, it's just to illustrate how quickly it can add up. Here is an example implementation, this project probably wouldn't want the Itoa (much better would be adding a simple Itoa to strings.Builder)- I was just toying around at that point to see how many more allocs I could spare, but that specific piece only saves at most the stack frame count.