Skip to content

Instantly share code, notes, and snippets.

@tzaffi
Created November 22, 2021 15:11
Show Gist options
  • Save tzaffi/021a382c9a7421e722be4e246ffb11a9 to your computer and use it in GitHub Desktop.
Save tzaffi/021a382c9a7421e722be4e246ffb11a9 to your computer and use it in GitHub Desktop.
Go: Faster to assign / swap slice fields in structs than parent structs
type aStruct struct {
aSlice []byte
}
func BenchmarkStructSwapping(b *testing.B) {
ssize := 500
b.Run("naive", func(b *testing.B) {
theStructs := make([]aStruct, b.N*2)
for i := 0; i < b.N; i++ {
theStructs[i].aSlice = make([]byte, ssize)
theStructs[i+b.N].aSlice = make([]byte, ssize)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
theStructs[i], theStructs[i+b.N] = theStructs[i+b.N], theStructs[i]
}
})
b.Run("inslice", func(b *testing.B) {
theStructs := make([]aStruct, b.N*2)
for i := 0; i < b.N; i++ {
theStructs[i].aSlice = make([]byte, ssize)
theStructs[i+b.N].aSlice = make([]byte, ssize)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
theStructs[i].aSlice, theStructs[i+b.N].aSlice = theStructs[i+b.N].aSlice, theStructs[i].aSlice
}
})
}
@tzaffi
Copy link
Author

tzaffi commented Nov 22, 2021

The following benchmark results show that swapping 500 byte slices inside of a struct is around 5x faster than swapping the container structs on an Intel based Macbook Pro.

Running tool: /usr/local/opt/go/libexec/bin/go test -benchmem -run=^$ -bench ^BenchmarkStructSwapping$ github.com/algorand/go-algorand/data/transactions/logic

goos: darwin
goarch: amd64
pkg: github.com/algorand/go-algorand/data/transactions/logic
cpu: Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz
BenchmarkStructSwapping/naive-8         	420369878	       104.8 ns/op	       0 B/op	       0 allocs/op
BenchmarkStructSwapping/inslice-8       	100000000	        22.32 ns/op	       0 B/op	       0 allocs/op
PASS
ok  	github.com/algorand/go-algorand/data/transactions/logic	485.816s

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