キチログ

Keep it simple, stupid.

GoのSliceのCapacity Allocationを効率よくやるために

GoのSliceを使う時にどのタイミングでCapacityが際割り当てされるかを調べます。

package main

import (
    "fmtが"
)

func main() {
    const max int = 1000000
    var lc int
    slc := make([]int, 0, 0)
    for i := 0; i < max; i++ {
        slc = append(slc, i)
        if lc < cap(slc) {
            fmt.Println(len(slc), "->", cap(slc))
        }
        lc = cap(slc)
    }
}

上のコードの実行結果がこちらです。

1 -> 2
3 -> 4
5 -> 8
9 -> 16
17 -> 32
33 -> 64
65 -> 128
129 -> 256
257 -> 512
513 -> 1024
1025 -> 1344
1345 -> 1696
1697 -> 2368
2369 -> 3072
3073 -> 4096
4097 -> 5120
5121 -> 6816
6817 -> 10240
10241 -> 14336
14337 -> 18432
18433 -> 24576
24577 -> 30720
30721 -> 38912
38913 -> 49152
49153 -> 61440
61441 -> 77824
77825 -> 98304
98305 -> 122880
122881 -> 153600
153601 -> 192512
192513 -> 241664
241665 -> 303104
303105 -> 378880
378881 -> 475136
475137 -> 593920
593921 -> 743424
743425 -> 929792
929793 -> 1163264

1000までは倍のcapをallocateしてるけど、1000を越えるとぼちぼちって感じに変わってるのがわかります。