Skip to content

Instantly share code, notes, and snippets.

@manigandand
Created April 25, 2021 17:22
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save manigandand/cfca280935f0ad91595c8f87e1c55af6 to your computer and use it in GitHub Desktop.
Save manigandand/cfca280935f0ad91595c8f87e1c55af6 to your computer and use it in GitHub Desktop.
Slice: append vs set performance comparison
package main
import (
"fmt"
"reflect"
"strings"
"unsafe"
)
func main() {
// var a []int
// c := make([]int, 10)
// d := make([]int, 0, 10)
// fmt.Printf("normal slice \ta: %v, len %d, cap: %d\n", a, len(a), cap(a))
// fmt.Printf("slice_len_cap same \tc: %v, len %d, cap: %d\n", c, len(c), cap(c))
// fmt.Printf("slice_len_cap not same \td: %v, len %d, cap: %d\n", d, len(d), cap(d))
fmt.Println(strings.Repeat("-", 25))
fmt.Println("testAppend()...")
testAppend()
fmt.Println(strings.Repeat("-", 25))
fmt.Println(strings.Repeat("-", 25))
fmt.Println("testAppendSliceLenCapSame()...")
testAppendSliceLenCapSame()
fmt.Println(strings.Repeat("-", 25))
fmt.Println(strings.Repeat("-", 25))
fmt.Println("testAppendSliceLenCapNotSame()...")
testAppendSliceLenCapNotSame()
fmt.Println(strings.Repeat("-", 25))
}
func testAppend() {
var result []int
fmt.Printf("normal slice \ta: %v, len %d, cap: %d\n", result, len(result), cap(result))
for i := 0; i < 5; i++ {
fmt.Printf("appending '%d': %s\n", i, getSliceHeader(&result))
result = append(result, i)
fmt.Printf("appended '%d': %s\n", i, getSliceHeader(&result))
}
fmt.Println(result)
fmt.Printf("normal slice \ta: %v, len %d, cap: %d\n", result, len(result), cap(result))
}
// len & cap same
func testAppendSliceLenCapSame() {
var result = make([]int, 5)
fmt.Printf("slice_len_cap same \tb: %v, len %d, cap: %d\n", result, len(result), cap(result))
for i := 0; i < 5; i++ {
fmt.Printf("appending '%d': %s\n", i, getSliceHeader(&result))
result = append(result, i)
fmt.Printf("appended '%d': %s\n", i, getSliceHeader(&result))
}
fmt.Println(result)
fmt.Printf("slice_len_cap same \tb: %v, len %d, cap: %d\n", result, len(result), cap(result))
}
// len 0
func testAppendSliceLenCapNotSame() {
var result = make([]int, 0, 5)
fmt.Printf("slice_len_cap not same \td: %v, len %d, cap: %d\n", result, len(result), cap(result))
for i := 0; i < 5; i++ {
fmt.Printf("appending '%d': %s\n", i, getSliceHeader(&result))
result = append(result, i)
fmt.Printf("appended '%d': %s\n", i, getSliceHeader(&result))
}
fmt.Println(result)
fmt.Printf("slice_len_cap not same \td: %v, len %d, cap: %d\n", result, len(result), cap(result))
}
func getSliceHeader(slice *[]int) string {
sh := (*reflect.SliceHeader)(unsafe.Pointer(slice))
return fmt.Sprintf("%+v", sh)
}
package main
import "testing"
func BenchmarkTestAppend(b *testing.B) {
var a []int
for i := 0; i < b.N; i++ {
a = append(a, i)
}
}
func BenchmarkTestAppendSliceLenCapSame(b *testing.B) {
a := make([]int, b.N)
for i := 0; i < b.N; i++ {
a = append(a, i)
}
}
func BenchmarkTestAppendSliceLenCapNotSame(b *testing.B) {
a := make([]int, 0, b.N)
for i := 0; i < b.N; i++ {
a = append(a, i)
}
}
func BenchmarkSliceSet(b *testing.B) {
a := make([]int, b.N)
for i := 0; i < b.N; i++ {
a[i] = i
}
}
@manigandand
Copy link
Author

image

@manigandand
Copy link
Author

Benchmark:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment