如果已经分配了内存,则x = append(x,a …)的序列在Go中非常有效。
在您的示例中,初始分配(制造)的成本可能比附加序列的成本高。这取决于字段的大小。考虑以下基准:
package mainimport ( "testing")const sizeTotal = 25var res []byte // To enforce heap allocationfunc BenchmarkWithAlloc(b *testing.B) { a := []byte("abcde") for i := 0; i < b.N; i++ { x := make([]byte, 0, sizeTotal) x = append(x, a...) x = append(x, a...) x = append(x, a...) x = append(x, a...) x = append(x, a...) res = x // Make sure x escapes, and is therefore heap allocated }}func BenchmarkWithoutAlloc(b *testing.B) { a := []byte("abcde") x := make([]byte, 0, sizeTotal) for i := 0; i < b.N; i++ { x = x[:0] x = append(x, a...) x = append(x, a...) x = append(x, a...) x = append(x, a...) x = append(x, a...) res = x }}在我的盒子上,结果是:
testing: warning: no tests to runPASSBenchmarkWithAlloc 10000000 116 ns/op 32 B/op 1 allocs/opBenchmarkWithoutAlloc 50000000 24.0 ns/op 0 B/op 0 allocs/op
系统地重新分配缓冲区(甚至是很小的缓冲区)会使此基准测试速度至少慢5倍。
因此,您最好希望对此代码进行优化,以确保您不会为所构建的每个数据包重新分配缓冲区。相反,您应该保留缓冲区,并在每次编组操作中重用它。
您可以重置切片,同时使用以下语句保留其基础缓冲区的分配:
x = x[:0]



