go语言中切片(slice)的扩容策略

39 阅读1分钟

一、关键代码

go sdk版本:2.12.3

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
      }
   }
}

其中: oldCap:切片的当前容量; newcap:切片的新容量; newLen:切片的期望容量(即分配后,切片的长度)。

二、分配策略

从代码中可看出,切片的扩容策略为: 1、如果期望容量大于当前容量的两倍,则使用期望容量作为新容量; 2、 如果切片的当前容量小于 256 ,则将当前容量翻倍后作为新容量; 否则,将当前容量扩容x倍(这个x的值将从小切片的2倍平滑到大切片的1.25倍,即从2慢慢变成1.25),直到满足期望容量。