go: runtime: don't allocate when putting a bool into an interface
Shoving a bool into an interface probably doesn’t need to allocate. I imagine most binaries already have a static 1 byte and a static 0 byte somewhere whose address we could use in the interface’s data pointer.
bradfitz@gdev:~$ cat alloc.go
package main
import "testing"
func main() {
var x interface{}
x = true
println(x)
x = false
println(x)
x = true
println(x)
println(testing.AllocsPerRun(5000, func() {
x = true
}))
}
bradfitz@gdev:~$ go run ~/alloc.go
(0x49b960,0xc42003bf4f)
(0x49b960,0xc42003bf4e)
(0x49b960,0xc42003bf4d)
+1.000000e+000
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 7
- Comments: 32 (25 by maintainers)
Commits related to this issue
- cmd/compile, runtime: convert byte-sized values to interfaces without allocation Based in part on khr's CL 2500. Updates #17725 Updates #18121 Change-Id: I744e1f92fc2104e6c5bd883a898c30b2eea8cc31 R... — committed to golang/go by josharian 7 years ago
- runtime: use zeroVal for small zero values in interfaces Fixes #17725 name old time/op new time/op delta ConvT2EInt/const-8 0.90ns ± 4% 0.90ns ± 2% ~ (p=0.623 n=2... — committed to josharian/go by josharian 7 years ago
Clearly we just need to smooth out that cliff with some
fastrand(), slowly increasing the chance of allocating from 0 to 1024, where 1025 is 100%! /sI was thinking we just have a 256-byte slab of “\x00\x01…\xff”, and we can index into that for any read-only 1-byte value that needs to be converted to a pointer (e.g., converting a len-1 []byte to string, or storing a bool/byte/int8/uint8 into an interface).
If we instead used […]int64{…, -3, -2, -1, 0, 1, 2, 3, …} for a certain range of integers, we could avoid heap allocs for a wider variety of values.
Agreed collecting stats on recognizable patterns would be good.
Relatedly, I’ve been thinking that converting len-1 []byte to string shouldn’t need to allocate either.