Go语言——Slice分析

2018-10-20  本文已影响0人  陈先生_9e91

Go语言——Slice分析

源码很不好找,在go\src\runtime\slice.go。

type slice struct {
   array unsafe.Pointer
   len   int
   cap   int
}
func makeslice(et *_type, len, cap int) slice {
   p := mallocgc(et.size*uintptr(cap), et, true)
   return slice{p, len, cap}
}

根据容量cap*元素size,申请一块内存。mallocgc大空间(大于32kb)才会在heap堆上申请,否则在栈上分配,具体以后再介绍。

这里我们就看到切片底层就是数组,特别的是切片可以增长。

grow

注释

// it returns a new slice with at least that capacity, with the old data
// copied into it.
// The new slice's length is set to the old slice's length,
// NOT to the new requested capacity.
// This is for codegen convenience. The old slice's length is used immediately
// to calculate where to write new values during an append.

Note:

  1. 方法返回的新切片容量至少达到请求,也就是说新的容量可能比申请的多;
  2. copy老数据,也就是说有性能损耗;
  3. len一致,因为数据内容不变.

cap

   newcap := old.cap
   doublecap := newcap + newcap
   if cap > doublecap {
      newcap = cap
   } else {
      if old.len < 1024 {
         newcap = doublecap
      } else {
         for newcap < cap {
            newcap += newcap / 4
         }
      }
   }

cap增长策略:

  1. 如果期望大于double,新cap就等于期望;
  2. 如果当前大小小于1024,则两倍增长;
  3. 否则每次增长25%,直到满足期望。
上一篇 下一篇

猜你喜欢

热点阅读