为什么使用`[:0]`时切片的容量不会减少?

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

why the slice's capacity does not decrease with `[:0]`

问题

我正在阅读《Go之旅》并对切片的一个案例感到困惑。

s = s[:0]

在这个操作之后,slen()变为0,但cap()没有减少。为什么容量没有减少?什么时候会想要使用这个“特性”?

英文:

I am reading A Tour of Go and get confused about a slicing case

s = s[:0]

After this operation, the len() of s becomes 0 but the cap() does not. Why is the capacity not decreased? When would one want to use this 'feature'?

答案1

得分: 6

你可以使用三索引切片来获取零截断的切片:

s = s[:0:0]

Playground: https://play.golang.org/p/YetCdJVWrB.

英文:

You can actually use the three-index slicing to get the zero-capped slice:

s = s[:0:0]

Playground: https://play.golang.org/p/YetCdJVWrB.

答案2

得分: 2

不修改容量的选择可能是为了性能优化。切片基本上是“动态数组”,它们意图提供数组容量无限的抽象。实际上,容量当然受系统内存的限制,但是如果一个切片已经达到容量上限,并且你向其添加一个元素,Go语言会为数组分配新的内存以提供容量(假设可用,否则你的应用程序将会崩溃)。

长度表示切片中实际可索引的元素数量,而容量告诉你底层内存的大小。当进行切片操作时,没有立即释放内存的必要,因此内存仍然被分配,这就是为什么切片的容量保持不变,但长度变为零的原因。

总体而言,这可能会提高应用程序的性能,因为如果后续语句向切片添加元素,内存仍然可用。实际上,你通常不需要担心容量。然而,我建议你将其牢记在心。

在我看来,最相关的情况是当你从某个源读取数据并且知道该数据的大小,或者至少有一个大致的想法,并将其放入切片中时。在这种情况下,如果你使用适当的容量初始化切片,你的应用程序将会更高效。如果你不提供长度或容量参数(如果只提供长度,则容量默认为长度),那么你可能会发现默认的切片增长效率相当低下,或者至少引入了可以很容易避免的低效率。

英文:

The choice to not modify the capacity is likely a performance optimization. Slices are basically 'dynamic arrays', they intend to provide the abstraction that the array's capacity is unlimited. In reality, capacity is of course limited by system memory, however if a slice is at capacity and you append an item to it, Go will allocate new memory for the array to provide that capacity (assuming it's available, if it's not your app will ofc panic).

The length represents the actual indexable item count in the slice, while the capacity tells you how much underlying memory is there. When you do those reslicing operations, there is no immediate need to free the memory and therefor it remains allocated, that is why the slices capacity remains unchanged but the length goes to zero.

Overall, this likely leads to better application performance since the memory is still available should subsequent statements append items to the slice. In practice you generally don't need to worry about capacity. I would recommend keeping it in the back of your mind however.

The times where it's most relevant, imo, is when you're reading data from some source and you know the size of that data, or at least have a rough idea, and you're putting that into a slice. In such a circumstance your application will perform better if you initialize the slice with an appropriate capacity. If you provide no length or capacity arguments (capacity defaults to length if only length is provided) then you may find the default slice growth is fairly inefficient, or at the very least, is introducing inefficiency that can quite easily be avoided.

huangapple
  • 本文由 发表于 2016年11月5日 04:42:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/40431396.html
匿名

发表评论

匿名网友

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

确定