golang slice 扩容策略变更

golang 1.18 之前的策略

func growslice(et *_type, old slice, cap int) slice {

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

如果期望容量大于当前容量的两倍就会使用期望容量;如果当前切片的长度小于 1024 就会将容量翻倍;如果当前切片的长度大于 1024 就会每次增加 25% 的容量,直到新容量大于期望容量;

1.18 开始的新策略

func growslice(et *_type, old slice, cap int) slice {
  
  newcap := old.cap
  doublecap := newcap + newcap
  if cap > doublecap {
    newcap = cap
  } else {
    const threshold = 256
    if old.cap < threshold {
      newcap = doublecap
    } else {
      // Check 0 < newcap to detect overflow
      // and prevent an infinite loop.
      for 0 < newcap && newcap < cap {
        // 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 = cap
      }
    }
  }
  • 如果期望容量大于当前容量的两倍就会使用期望容量;
  • !如果当前切片的长度小于 256 就会将容量翻倍;
  • !如果当前切片的长度大于 256 就会每次增加 (25% + 192) 的容量,直到新容量大于期望容量;

主要修改点在对于较大长度的 slice ,在 slice 稍小时可以约等于 double,对于稍大时可以 1.25 倍扩容,整体扩容更加平滑

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 今天开工第一天,2023 xdm 什么目标,评论区聊聊。今天我们来聊聊切片(Slice)。 1. 说在前面 在之前...
    程序员祝融阅读 526评论 0 1
  • array 特征 内存连续,可以根据索引获取元素. 初始化之后大小就无法改变. 存储元素类型相同、大小相同的两个数...
    kyo1992阅读 224评论 0 0
  • 看完这篇文章,下面这些高频面试题你都会答了吧 Go slice的底层实现原理 Go array和slice的区别 ...
    Go程序员阅读 1,941评论 0 4
  • 环境 初始化 下标 字面量 关键字 Compile Time cmd/compile/internal/types...
    七秒钟回忆待续阅读 1,028评论 1 1
  • 数组在 Go 语言中没那么常用,更常用的数据结构是切片,即动态数组,其长度并不固定,我们可以向切片中追加元素,它会...
    菩提树下参悟阅读 113评论 0 2