Go切片的容量增长速率

huangapple go评论65阅读模式
英文:

Go slices capacity increase rate

问题

我是你的中文翻译助手,以下是翻译好的内容:

我是Go语言的新手,正在阅读一本名为《Learning Go》的书,这本书是由O'Reilly出版的。在阅读有关切片的部分时,有如下一句话:

从Go 1.14版本开始,增加切片的大小的规则是,直到达到1024的大小之前,容量会翻倍,之后每次增长25%。

我编写了以下Go代码来证明这一点。

package main

import "fmt"

func main() {
	var length uint16 = 1024

	var x []int

	for i := 0; i < int(length); i++ {
		x = append(x, i)
		fmt.Printf("\nLength is %d. Capacity is %d", len(x), cap(x))
	}
}

从0到len(x)==512的时候,证明了Go运行时会将容量(即大小)翻倍。但是在这里,我对以下部分很感兴趣:当len(x) >= 512时,我期望容量为1024,因为512*2 = 1024。然而,结果如下:

Length is 513. Capacity is 848

所以容量大约增加了65%。有人可以解释一下这个问题吗?

英文:

I am new in Go and going through a book called "Learning Go" publised by O'reilly. While reading about Slices, there is a statement below:

> To increase the size of a slice, as of Go 1.14 the rule is that it doubles the capacity until reaching the size of 1024 and then grow by 25 % afterwards."

I wrote this Go code to prove it.

package main

import &quot;fmt&quot;

func main() {
	var length uint16 = 1024

	var x []int

	for i := 0; i &lt; int(length); i++ {
		x = append(x, i)
		fmt.Printf(&quot;\nLength is %d. Capacity is %d&quot;, len(x), cap(x))
	}
}

From 0 to len(x)==512 it is proven to be true that Go runtime doubles the capacity (a.k.a size). But here the interesting part for me starts: when the len(x) >= 512 I was expecting capacity to be 1024 as 512*2 = 1024. However the result is below:

Length is 513. Capacity is 848

So it is roughly a 65% increase. Can someone explain this to me?

答案1

得分: 16

截至Go 1.14版本,最新发布的是Go 1.20版本(发布于2023-02-01)。Go 1.21版本的工作已经开始。阅读Go源代码以查看自Go 1.14版本(发布于2020-02-25)以来的更改。

例如,

go/src/runtime/slice.go:

// 从对小切片增长2倍过渡到对大切片增长1.25倍。这个公式在两者之间提供了较为平滑的过渡。

runtime: 使切片增长公式更加平滑
(提交于2021年9月27日20:53:51):

不再对<1024个元素增长2倍,对>=1024个元素增长1.25倍,而是使用一个较为平滑的增长因子公式。在256个元素后开始逐渐减小增长因子。

初始容量    增长因子
256         2.0
512         1.63
1024        1.44
2048        1.35
4096        1.30

(请注意,实际的增长因子,无论之前还是现在,都要稍大一些,因为我们向上取整到下一个大小类。)
英文:

> as of Go 1.14

Go 1.20 has just been released (released 2023-02-01). Work has started on Go 1.21. Read the Go source code to see the changes since Go 1.14 (released 2020-02-25).

For example,

go/src/runtime/slice.go:

// Transition from growing 2x for small slices
// to growing 1.25x for large slices. This formula
// gives a smooth-ish transition between the two.

runtime: make slice growth formula a bit smoother
(Committed Mon Sep 27 20:53:51 2021):

Instead of growing 2x for &lt; 1024 elements and 1.25x for &gt;= 1024 elements,
use a somewhat smoother formula for the growth factor. Start reducing
the growth factor after 256 elements, but slowly.

starting cap    growth factor
256             2.0
512             1.63
1024            1.44
2048            1.35
4096            1.30

(Note that the real growth factor, both before and now, is somewhat
larger because we round up to the next size class.)

huangapple
  • 本文由 发表于 2023年2月5日 05:42:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/75348572.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定