在Go语言中,是否值得避免创建大小为0的切片?

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

In go, is it worth avoiding creating slices of size 0?

问题

我有一个程序,其中我将创建很多切片,其中一些可能是空的:

nb := something() // something可能返回0
slices = append(slices, make([]int, nb))

make([]int, 0)是否分配了一些内存,因此在内存效率上不如nil切片,尽管它们具有相同的行为?差距有多大?

如果是这样,是否值得进行测试以避免无用的分配,或者测试的CPU时间成本不值得在内存上节省(或者有其他原因不这样做)?

var sl slice
nb := something()
if nb > 0 {
    sl = make([]int, nb)
}
slices = append(slices, sl)
英文:

I have a program in which I'm going to make lots and lots of slices, some of which might be empty:

nb := something() // something might return 0
slices = append(slices, make([]int, nb))

Does make([]int, 0) allocates some memory and is, thus, less memory efficient than a nil slice although they share the same behavior ? By how much ?

If so, is it worth doing a test to avoid useless allocations, or is the CPU time cost of the test not worth the saving in memory (or any other reason not to do so) ?

var sl slice
nb := something()
if nb > 0 {
    sl = make([]int, nb)
}
slices = append(slices, sl)

答案1

得分: 4

var a []T // nil slicea := make([]T, 0) // zero-length, zero-capacity, non-nil slice之间,在分配的内存上没有区别。

区别在于切片头部的内容。在第二种情况下,切片指针包含了一个固定的地址,对于所有大小为0的分配都是相同的。

如果这段代码在程序的性能关键部分,这个区别会产生相当大的影响。在第一种情况下,你只需要将切片头部清零,而在第二种情况下,你需要经过3-4个函数调用,一些容量和长度的范围检查等等,然后malloc才会返回一个指向零基址的指针。

英文:

There is no difference in the allocated memory between

var a []T // nil slice

and

a := make([]T, 0) // zero-length, zero-capacity, non-nil slice

The difference is in the slice header content. In the second case the slice pointer contains some fixed address, same for all 0-sized allocations.

If this code is in a performance critical part of the program, the difference makes ... quite a difference. In the first case you do zero the slice header, in the second case you go through 3-4 function calls, some range checks for cap and length, etc. before malloc returns a pointer to the zero base.

答案2

得分: 3

> make([]int, 0) 分配了一些内存吗?

是的,它分配了一个切片头部,但没有分配后备数组。如果切片头部没有逃逸到当前作用域之外,它可能会在栈上分配。

> 比 nil 切片更节省内存吗?

就内存使用而言,它们是相同的。

> 值得进行测试以避免无用的分配吗?

一般来说,是的。与执行内存分配和初始化所需的周期相比,比较一个整数需要的3或4条指令微不足道。

英文:

> Does make([]int, 0) allocates some memory

Yes, it allocates a slice header but no backing array. If the slice header doesn't escape the current scope it may be allocated on the stack.

> less memory efficient than a nil slice

In terms of memory used, they're the same.

> is it worth doing a test to avoid useless allocations

In general yes, the 3 or 4 instructions it takes to compare an int are nothing compared to the cycles you'd need to do a memory allocation and initialization.

huangapple
  • 本文由 发表于 2015年10月23日 17:58:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/33299616.html
匿名

发表评论

匿名网友

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

确定