英文:
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 slice
和a := 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论