スライスに要素を詰めていく時のお話


はじめに

スライスに要素を詰めていく時に、記述の仕方でどれくらいパフォーマンス変わってくるかベンチマークで検証。
パフォーマンスチューニングにて活かしたい。

appendを使う場合

要素数分capacityを確保しておくと良い。
例えば要素数が10であるときはcapacityで10を指定しておく。

func makeSlice() {
    s := make([]int, 0, 10)

    for i:=0; i<10; i++ {
        s = append(s, i)
    }
}
BenchmarkMakeSlice-4    83859099                13.5 ns/op
PASS
ok      awesomeProject2 1.157s

確保できていない場合、例えばcapacityを5とした時、

func makeSlice() {
    s := make([]int, 0, 5)

    for i:=0; i<10; i++ {
        s = append(s, i)
    }
}
BenchmarkMakeSlice-4    17901537                61.9 ns/op
PASS
ok      awesomeProject2 1.187s

capacityを3とした時、

BenchmarkMakeSlice-4    10131793               118 ns/op
PASS
ok      awesomeProject2 1.327s

以下の場合、

func makeSlice() {
    var s []int

    for i:=0; i<10; i++ {
        s = append(s, i)
    }
}
BenchmarkMakeSlice-4     4877806               246 ns/op
PASS
ok      awesomeProject2 1.468s

事前に要素数がわかっている場合はインデックスを活用

事前に要素数がわかっている場合は、インデックスを活用して代入していく方がappendを用いるよりも速くなる。

func makeSlice() {
    s := make([]int, 10)

    for i:=0; i<10; i++ {
        s[i]=i
    }
}
BenchmarkMakeSlice-4    184096501                6.39 ns/op
PASS
ok      awesomeProject2 1.844s