-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (go version)?
1.8
What operating system and processor architecture are you using (go env)?
GOOS=darwin
GOARCH=amd64
What, why, etc.
While profiling an ORM-like program, I discovered most of the 100+ allocs/op were from calls to strconv.Itoa. By implementing a simple cache in front of strconv.Itoa, the number of allocs dropped by over half and so did the runtime of the function (7 to 3 μs). I looked at some other of our projects and noticed most of the Itoa-like calls were used to format smaller numbers (i.e., < 100). I'd imagine other project that generate SQL or graph query code and need to format parameters ($1, $2, ...) would see decent performance improvements as well.
A small test I ran shows no appreciable difference when the majority of N is > 99 or N is a pseudo-random number in [0, b.N), but runs in 1/10 the time where N < 100 and doesn't incur any allocations.
My issues with this idea:
- Small range of numbers (assumes that most calls are < 100)
- Only works with base 10
- Negative numbers need their own cache or an alloc needs to be made to contact the number with "-"
FWIW the cache only needs to be a 190-byte long string.
name old time/op new time/op delta
SmallItoaAll-4 45.8ns ± 0% 47.4ns ± 0% ~ (p=1.000 n=1+1)
SmallItoaRand-4 90.9ns ± 0% 90.5ns ± 0% ~ (p=1.000 n=1+1)
SmallItoa-4 31.4ns ± 0% 3.4ns ± 0% ~ (p=1.000 n=1+1)
name old alloc/op new alloc/op delta
SmallItoaAll-4 8.00B ± 0% 8.00B ± 0% ~ (all equal)
SmallItoaRand-4 7.00B ± 0% 7.00B ± 0% ~ (all equal)
SmallItoa-4 1.00B ± 0% 0.00B ~ (p=1.000 n=1+1)
name old allocs/op new allocs/op delta
SmallItoaAll-4 1.00 ± 0% 1.00 ± 0% ~ (all equal)
SmallItoaRand-4 1.00 ± 0% 0.00 ~ (p=1.000 n=1+1)
SmallItoa-4 1.00 ± 0% 0.00 ~ (p=1.000 n=1+1)