Performance and Benchmarking Basics
Slice Preallocation
Preallocating a slice can make growth intent explicit and avoid repeated capacity changes.
preallocation
Use `make` with capacity when code already knows the likely number of appended values.
Slice Preallocation
slice_preallocation.go
Replay: real traced execution (multi-file project)
package main
import "fmt"
func main() {
var expected = 3
values := make([]int, 0, expected)
for i := 0; i < expected; i++ {
values = append(values, i*i)
}
fmt.Println("expected=", expected)
fmt.Println("length=", len(values))
fmt.Println("capacity=", cap(values))
fmt.Println("values=", values)
}
package main
import "fmt"
func main() {
var expected = 1
values := make([]int, 0, expected)
for i := 0; i < expected; i++ {
values = append(values, i*i)
}
fmt.Println("expected=", expected)
fmt.Println("length=", len(values))
fmt.Println("capacity=", cap(values))
fmt.Println("values=", values)
}
package main
import "fmt"
func main() {
var expected = 5
values := make([]int, 0, expected)
for i := 0; i < expected; i++ {
values = append(values, i*i)
}
fmt.Println("expected=", expected)
fmt.Println("length=", len(values))
fmt.Println("capacity=", cap(values))
fmt.Println("values=", values)
}
expected ← 3, values ← []int{}
5func main() {6 var expected→ 3 = 3 //@expected=1, 57 values→ []int{} := make([]int, 0, expected3)8 for i := 0; i < expected; i++ {values ← []int{0}
pass 1 of 37values := make([]int, 0, expected)8for i0 := 0; i < expected3; i++ {9 values→ []int{0} = append(values, i0*i)10}All 3 passes — pass 1 is the card above pass ivalues1 0 []int{} → []int{0} 2 1 []int{0} → []int{0, 1} 3 2 []int{0, 1} → []int{0, 1, 4} fmt.Println("expected=", expected)
12 fmt.Println("expected=", expected3)13 fmt.Println("length=", len(values[]int{0, 1, 4}))14 fmt.Println("capacity=", cap(values[]int{0, 1, 4}))15 fmt.Println("values=", values[]int{0, 1, 4})16}outputexpected= 3 length= 3 capacity= 3 values= [0 1 4]
expected ← 1, values ← []int{}
5func main() {6 var expected→ 1 = 17 values→ []int{} := make([]int, 0, expected1)8 for i := 0; i < expected; i++ {values ← []int{0}
7values := make([]int, 0, expected)8for i0 := 0; i < expected1; i++ {9 values→ []int{0} = append(values, i0*i)10}fmt.Println("expected=", expected)
12 fmt.Println("expected=", expected1)13 fmt.Println("length=", len(values[]int{0}))14 fmt.Println("capacity=", cap(values[]int{0}))15 fmt.Println("values=", values[]int{0})16}outputexpected= 1 length= 1 capacity= 1 values= [0]
expected ← 5, values ← []int{}
5func main() {6 var expected→ 5 = 57 values→ []int{} := make([]int, 0, expected5)8 for i := 0; i < expected; i++ {values ← []int{0}
pass 1 of 57values := make([]int, 0, expected)8for i0 := 0; i < expected5; i++ {9 values→ []int{0} = append(values, i0*i)10}All 5 passes — pass 1 is the card above pass ivalues1 0 []int{} → []int{0} 2 1 []int{0} → []int{0, 1} 3 2 []int{0, 1} → []int{0, 1, 4} 4 3 []int{0, 1, 4} → []int{0, 1, 4, 9} 5 4 []int{0, 1, 4, 9} → []int{0, 1, 4, 9, 16} fmt.Println("expected=", expected)
12 fmt.Println("expected=", expected5)13 fmt.Println("length=", len(values[]int{0, 1, 4, 9, 16}))14 fmt.Println("capacity=", cap(values[]int{0, 1, 4, 9, 16}))15 fmt.Println("values=", values[]int{0, 1, 4, 9, 16})16}outputexpected= 5 length= 5 capacity= 5 values= [0 1 4 9 16]