Go Counting Allocations
Counting allocations means counting how many times code asks for new memory while it runs. The testing package gives AllocsPerRun, a function that runs code and reports that count.
Join with a Builder
A strings.Builder builds the word go five times. AllocsPerRun runs the work and prints its count.
package main
import (
"fmt"
"strings"
"testing"
)
func main() {
count := testing.AllocsPerRun(10, func() {
var b strings.Builder
for i := 0; i < 5; i++ {
b.WriteString("go")
}
_ = b.String()
})
fmt.Println(count)
}Join with +=
The += operator joins the same five pieces into a string. The same counting call prints its count.
package main
import (
"fmt"
"testing"
)
func main() {
count := testing.AllocsPerRun(10, func() {
s := ""
for i := 0; i < 5; i++ {
s += "go"
}
_ = s
})
fmt.Println(count)
}A loop that stores nothing
A loop over a fixed array adds the numbers into one plain int. Nothing new is stored while the loop runs.
package main
import (
"fmt"
"testing"
)
func main() {
count := testing.AllocsPerRun(10, func() {
nums := [5]int{1, 2, 3, 4, 5}
total := 0
for _, n := range nums {
total += n
}
_ = total
})
fmt.Println(count)
}Example
package main
import (
"fmt"
"strings"
"testing"
)
func main() {
builder := testing.AllocsPerRun(10, func() {
var b strings.Builder
for i := 0; i < 5; i++ {
b.WriteString("go")
}
_ = b.String()
})
plus := testing.AllocsPerRun(10, func() {
s := ""
for i := 0; i < 5; i++ {
s += "go"
}
_ = s
})
fmt.Println("Builder:", builder)
fmt.Println("Plus:", plus)
}Key points
- An allocation is one request for new memory while the program runs.
- AllocsPerRun runs a function many times and returns the average number of allocations for one run.
- AllocsPerRun returns its average as a decimal number, so a whole average prints as 2.
- A strings.Builder keeps one buffer for the pieces it joins, so it allocates less often.
- Joining with += makes a new string at each step, so the count grows.
- Code that only reads fixed values and keeps a plain number can allocate zero times.
In this example, one program counts both joins and prints each count with a label. The Builder count prints first, and the += count prints second. The Builder takes 2 allocations, and the += join takes 4.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Go Playground
Exercise
Which join took fewer allocations in this lesson?