The Go Programming Language Specification
Appending to and copying slices
可変引数関数アペンドはまた、スライスタイプでなければならない タイプSのS、ゼロ以上の値xを追加し、得られたスライスを返し、
append(s S, x ...T) S // T is the element type of S
sの容量が十分でない場合 appendは、既存のスライス要素と追加値の両方に合わせて、十分に大きな新しい基本配列を割り当てます( )。それ以外の場合は、 を追加して、基になる配列を再利用します。
たとえば、操作あたり平均で[40,41]バイトが割り当てられ、必要に応じてスライスの容量が増えます。容量は、償却された一定時間アルゴリズムを使用して増加されます。最大len 1024まで増加させて2倍キャップにし、キャップの1.25倍に増加させます。平均して、操作ごとに[0、1]の割り当てがあります。
例えば、
func BenchmarkMem(b *testing.B) {
b.ReportAllocs()
var x []int64
var a, ac int64
b.ResetTimer()
for i := 0; i < b.N; i++ {
c := cap(x)
x = append(x, int64(i))
if cap(x) != c {
a++
ac += int64(cap(x))
}
}
b.StopTimer()
sizeInt64 := int64(8)
B := ac * sizeInt64 // bytes
b.Log("op", b.N, "B", B, "alloc", a, "lx", len(x), "cx", cap(x))
}
出力:
op = 50000000
については
BenchmarkMem-4 50000000 26.6 ns/op 40 B/op 0 allocs/op
--- BENCH: BenchmarkMem-4
bench_test.go:32: op 1 B 8 alloc 1 lx 1 cx 1
bench_test.go:32: op 100 B 2040 alloc 8 lx 100 cx 128
bench_test.go:32: op 10000 B 386296 alloc 20 lx 10000 cx 12288
bench_test.go:32: op 1000000 B 45188344 alloc 40 lx 1000000 cx 1136640
bench_test.go:32: op 50000000 B 2021098744 alloc 57 lx 50000000 cx 50539520
、
B/op = floor(2021098744/50000000) = floor(40.421974888) = 40
allocs/op = floor(57/50000000) = floor(0.00000114) = 0
読む:
Go Slices: usage and internals
'append' complexity
Arrays, slices (and strings): The mechanics of 'append'は、追記のためにゼロB/OP(ゼロallocs/OP)を有する追加する前に、十分な容量を持つスライスを割り当てます。例えば
、var x = make([]int64, 0, b.N)
、
func BenchmarkZero(b *testing.B) {
b.ReportAllocs()
var x = make([]int64, 0, b.N)
var a, ac int64
b.ResetTimer()
for i := 0; i < b.N; i++ {
c := cap(x)
x = append(x, int64(i))
if cap(x) != c {
a++
ac += int64(cap(x))
}
}
b.StopTimer()
sizeInt64 := int64(8)
B := ac * sizeInt64 // bytes
b.Log("op", b.N, "B", B, "alloc", a, "lx", len(x), "cx", cap(x))
}
出力を有する:
BenchmarkZero-4 100000000 11.7 ns/op 0 B/op 0 allocs/op
--- BENCH: BenchmarkZero-4
bench_test.go:51: op 1 B 0 alloc 0 lx 1 cx 1
bench_test.go:51: op 100 B 0 alloc 0 lx 100 cx 100
bench_test.go:51: op 10000 B 0 alloc 0 lx 10000 cx 10000
bench_test.go:51: op 1000000 B 0 alloc 0 lx 1000000 cx 1000000
bench_test.go:51: op 100000000 B 0 alloc 0 lx 100000000 cx 100000000
注/ OP周り26.6ナノ秒から/ OP周り11.7ナノ秒にベンチマークCPU時間の短縮。
質問3のアイデアですか? –