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

/cc @josharian @randall77 @mdempsky

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 7
  • Comments: 32 (25 by maintainers)

Commits related to this issue

Most upvoted comments

We ended up not using it because the performance cliff from 1024->1025 would be weird.

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%! /s

I 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.