Go-Slice的扩容机制

查看Go的不同版本:https://go.googlesource.com/go/+refs

源码位置
src/runtime/slice.go :func growslice(xxx)

1.18之前

如果原Slice容量小于1024,则新Slice容量将扩大为原来的2倍;

如果原Slice容量大于等于1024,则新Slice容量将扩大为原来的1.25倍,即1 / 4

newcap := old.cap
    doublecap := newcap + newcap
    if cap > doublecap {
        newcap = cap
    } else {
        if old.cap < 1024 {
            newcap = doublecap
        } else {
            // Check 0 < newcap to detect overflow
            // and prevent an infinite loop.
            for 0 < newcap && newcap < cap {
                newcap += newcap / 4
            }
            // Set newcap to the requested cap when
            // the newcap calculation overflowed.
            if newcap <= 0 {
                newcap = cap
            }
        }
    }

1.18之后

go在这次提交中 runtime: make slice growth formula a bit smoother修改了扩容规则

用一个更平滑的公式来计算扩容因子,在256个元素之前还是2倍扩容因子,在256个元素后逐步减少,不同容量下的扩容因子如下:

 

从小切片的增长2x过渡到大切片的增长1.25x
这个公式给出了两者之间的平滑过渡

    newcap := oldCap
    doublecap := newcap + newcap
    if newLen > doublecap {
        newcap = newLen
    } else {
        const threshold = 256
        if oldCap < threshold {
            newcap = doublecap
        } else {
            // Check 0 < newcap to detect overflow
            // and prevent an infinite loop.
            for 0 < newcap && newcap < newLen {
                // Transition from growing 2x for small slices
                // to growing 1.25x for large slices. This formula
                // gives a smooth-ish transition between the two.
                newcap += (newcap + 3*threshold) / 4
            }
            // Set newcap to the requested cap when
            // the newcap calculation overflowed.
            if newcap <= 0 {
                newcap = newLen
            }
        }
    }

总结

  • 1.18以前:

    • 容量小于1024时为2倍扩容,大于等于1024时为1.25倍扩容
  • 1.18以后:

    • 小于256时为2倍扩容,大于等于256时的扩容因子逐渐从2减低为1.25

 

posted @ 2023-04-29 10:52  GJH-  阅读(89)  评论(0编辑  收藏  举报