Go by Example: Performance: Slice-Append

Compare and benchmark 3 kinds of slice append
ref: Arrays, slices (and strings): The mechanics of ‘append’ ref: Golang slice append vs assign performance

package main
const length = 1000

1) genByAppend will encountered several times of re-allocation as the slice grows. Process includes:
- re-allocate a new array with doubled size
- copy the existing array data to new one
- change the slice pointer to array
- append

func genByAppend() []int {
    var s []int
    for i := 0; i < length; i++ {
        s = append(s, i)
    }
    return s
}

2) genByAppendCap pre-allocated the capacity of length
- already allocated enough space.
- should not trigger the re-allocation
- however the local variable s (which is a slice header) has to be updated in each cycle of the loop.

func genByAppendCap() []int {
    s := make([]int, 0, length)
    for i := 0; i < length; i++ {
        s = append(s, i)
    }
    return s
}

3) genByAssign is the fastest among 3, because of directly assignment.

func genByAssign() []int {
    s := make([]int, length)
    for i := 0; i < length; i++ {
        s[i] = i
    }
    return s
}
$ go test -v -bench=. 
goos: darwin
goarch: arm64
pkg: github.com/hhow09/gobyexample/examples/performance-slice-append
BenchmarkGenByAppend
BenchmarkGenByAppend-8            563953              2148 ns/op
BenchmarkGenByAppendCap
BenchmarkGenByAppendCap-8        2595301               455.5 ns/op
BenchmarkGenByAssign
BenchmarkGenByAssign-8           4048084               294.9 ns/op
PASS
ok      github.com/hhow09/gobyexample/examples/performance-slice-append 5.483s

Next example: Select.