このページについて
go でよく話題に上がるsliceで事前に容量を渡す場合とそうでない場合で
どの程度パフォーマンスに差分があるか簡単に見れるように試してみました。
内容
サンプルコード
main.go
package slices
func AllocationSlice(from []string, to []string) {
for _, item := range from {
to = append(to, item)
}
}
ベンチマークコード
main_test.go
package slices
import "testing"
func StrSlice(num int) []string {
re := make([]string, num, num)
for idx, _ := range re {
re[idx] = "a"
}
return re
}
func BenchmarkAllocationSlice(b *testing.B) {
type args struct {
from []string
to []string
}
tests := []struct {
name string
args args
}{
{
name: "pre_alloc_100",
args: args{
from: StrSlice(100),
to: make([]string, 0, 100),
},
},
{
name: "no_alloc_100",
args: args{
from: StrSlice(100),
to: []string{},
},
},
{
name: "pre_alloc_500",
args: args{
from: StrSlice(500),
to: make([]string, 0, 500),
},
},
{
name: "no_alloc_500",
args: args{
from: StrSlice(500),
to: []string{},
},
},
{
name: "pre_alloc_1000",
args: args{
from: StrSlice(1000),
to: make([]string, 0, 1000),
},
},
{
name: "no_alloc_1000",
args: args{
from: StrSlice(1000),
to: []string{},
},
},
{
name: "pre_alloc_3000",
args: args{
from: StrSlice(3000),
to: make([]string, 0, 3000),
},
},
{
name: "no_alloc_3000",
args: args{
from: StrSlice(3000),
to: []string{},
},
},
}
for _, tt := range tests {
b.Run(tt.name, func(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
AllocationSlice(tt.args.from, tt.args.to)
}
})
}
}
結果
goos: darwin
goarch: amd64
BenchmarkAllocationSlice/pre_alloc_100-8 10442223 114 ns/op 0 B/op 0 allocs/op
BenchmarkAllocationSlice/no_alloc_100-8 933322 1261 ns/op 4080 B/op 8 allocs/op
BenchmarkAllocationSlice/pre_alloc_500-8 2157058 547 ns/op 0 B/op 0 allocs/op
BenchmarkAllocationSlice/no_alloc_500-8 304494 4070 ns/op 16368 B/op 10 allocs/op
BenchmarkAllocationSlice/pre_alloc_1000-8 1000000 1076 ns/op 0 B/op 0 allocs/op
BenchmarkAllocationSlice/no_alloc_1000-8 168874 7100 ns/op 32752 B/op 11 allocs/op
BenchmarkAllocationSlice/pre_alloc_3000-8 362504 3205 ns/op 0 B/op 0 allocs/op
BenchmarkAllocationSlice/no_alloc_3000-8 33088 35524 ns/op 178801 B/op 15 allocs/op
PASS
ok github.com/smith-30/gopg/slices 13.624s
まとめ
場合によっては、速度に10倍以上差が出るので細かいところだけど気を使っていきたい