Go 的 slice 擴容倍率在大 slice 時還是 2 倍嗎

文章說「cap 的擴展會是 1, 2, 4, 8, 16, …」。小 slice 實測符合,但大 slice 是否還維持 2 倍,尚未驗證

我的理解是 Go 1.18 起改成漸進式的成長係數:超過某個門檻(印象中約 256 個元素)之後,倍率會從 2 逐步降到約 1.25,避免大 slice 一次要到過多記憶體。這一點還沒實測。

驗證方法(跑到 2000 個元素、印出每次 cap 變化):

var g []int
prev := -1
for i := 0; i < 2000; i++ {
    g = append(g, i)
    if cap(g) != prev {
        fmt.Println(len(g), cap(g))
        prev = cap(g)
    }
}

不論答案是什麼,實務結論不變:不要依賴 cap 的具體數字,已知數量就自己 prealloc(見 append 的行為取決於 cap 夠不夠)。這條問題的價值在於知道「那串 1,2,4,8,16 不能當成規格背」。

相關:append 的行為取決於 cap 夠不夠