1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
13 func BenchmarkMakeSlice(b
*testing
.B
) {
15 for i
:= 0; i
< b
.N
; i
++ {
21 func BenchmarkGrowSliceBytes(b
*testing
.B
) {
23 var x
= make([]byte, 9)
25 for i
:= 0; i
< b
.N
; i
++ {
26 _
= append([]byte(nil), x
...)
30 func BenchmarkGrowSliceInts(b
*testing
.B
) {
32 var x
= make([]int, 9)
34 for i
:= 0; i
< b
.N
; i
++ {
35 _
= append([]int(nil), x
...)
39 func BenchmarkGrowSlicePtr(b
*testing
.B
) {
41 var x
= make([]*byte, 9)
43 for i
:= 0; i
< b
.N
; i
++ {
44 _
= append([]*byte(nil), x
...)
48 type struct24
struct{ a
, b
, c
int64 }
50 func BenchmarkGrowSliceStruct24Bytes(b
*testing
.B
) {
52 var x
= make([]struct24
, 9)
54 for i
:= 0; i
< b
.N
; i
++ {
55 _
= append([]struct24(nil), x
...)
59 func BenchmarkAppend(b
*testing
.B
) {
61 x
:= make([]int, 0, N
)
63 for i
:= 0; i
< b
.N
; i
++ {
65 for j
:= 0; j
< N
; j
++ {
71 func BenchmarkAppendGrowByte(b
*testing
.B
) {
72 for i
:= 0; i
< b
.N
; i
++ {
74 for j
:= 0; j
< 1<<20; j
++ {
75 x
= append(x
, byte(j
))
80 func BenchmarkAppendGrowString(b
*testing
.B
) {
82 for i
:= 0; i
< b
.N
; i
++ {
84 for j
:= 0; j
< 1<<20; j
++ {
90 func BenchmarkAppendSlice(b
*testing
.B
) {
91 for _
, length
:= range []int{1, 4, 7, 8, 15, 16, 32} {
92 b
.Run(fmt
.Sprint(length
, "Bytes"), func(b
*testing
.B
) {
93 x
:= make([]byte, 0, N
)
94 y
:= make([]byte, length
)
95 for i
:= 0; i
< b
.N
; i
++ {
107 func BenchmarkAppendSliceLarge(b
*testing
.B
) {
108 for _
, length
:= range []int{1 << 10, 4 << 10, 16 << 10, 64 << 10, 256 << 10, 1024 << 10} {
109 y
:= make([]byte, length
)
110 b
.Run(fmt
.Sprint(length
, "Bytes"), func(b
*testing
.B
) {
111 for i
:= 0; i
< b
.N
; i
++ {
113 blackhole
= append(blackhole
, y
...)
119 func BenchmarkAppendStr(b
*testing
.B
) {
120 for _
, str
:= range []string{
125 "12345678901234567890123456789012",
127 b
.Run(fmt
.Sprint(len(str
), "Bytes"), func(b
*testing
.B
) {
128 x
:= make([]byte, 0, N
)
129 for i
:= 0; i
< b
.N
; i
++ {
131 x
= append(x
, str
...)
137 func BenchmarkAppendSpecialCase(b
*testing
.B
) {
139 x
:= make([]int, 0, N
)
141 for i
:= 0; i
< b
.N
; i
++ {
143 for j
:= 0; j
< N
; j
++ {
161 func TestSideEffectOrder(t
*testing
.T
) {
162 x
= make([]int, 0, 10)
163 x
= append(x
, 1, f())
164 if x
[0] != 1 || x
[1] != 2 {
165 t
.Error("append failed: ", x
[0], x
[1])
169 func TestAppendOverlap(t
*testing
.T
) {
171 x
= append(x
[1:], x
...) // p > q in runtimeĀ·appendslice.
175 t
.Errorf("overlap failed: got %q want %q", got
, want
)
179 func BenchmarkCopy(b
*testing
.B
) {
180 for _
, l
:= range []int{1, 2, 4, 8, 12, 16, 32, 128, 1024} {
181 buf
:= make([]byte, 4096)
182 b
.Run(fmt
.Sprint(l
, "Byte"), func(b
*testing
.B
) {
185 for i
:= 0; i
< b
.N
; i
++ {
190 b
.Run(fmt
.Sprint(l
, "String"), func(b
*testing
.B
) {
191 s
:= string(make([]byte, l
))
193 for i
:= 0; i
< b
.N
; i
++ {
209 // BenchmarkAppendInPlace tests the performance of append
210 // when the result is being written back to the same slice.
211 // In order for the in-place optimization to occur,
212 // the slice must be referred to by address;
213 // using a global is an easy way to trigger that.
214 // We test the "grow" and "no grow" paths separately,
215 // but not the "normal" (occasionally grow) path,
216 // because it is a blend of the other two.
217 // We use small numbers and small sizes in an attempt
218 // to avoid benchmarking memory allocation and copying.
219 // We use scalars instead of pointers in an attempt
220 // to avoid benchmarking the write barriers.
221 // We benchmark four common sizes (byte, pointer, string/interface, slice),
222 // and one larger size.
223 func BenchmarkAppendInPlace(b
*testing
.B
) {
224 b
.Run("NoGrow", func(b
*testing
.B
) {
227 b
.Run("Byte", func(b
*testing
.B
) {
228 for i
:= 0; i
< b
.N
; i
++ {
229 sByte
= make([]byte, C
)
230 for j
:= 0; j
< C
; j
++ {
231 sByte
= append(sByte
, 0x77)
236 b
.Run("1Ptr", func(b
*testing
.B
) {
237 for i
:= 0; i
< b
.N
; i
++ {
238 s1Ptr
= make([]uintptr, C
)
239 for j
:= 0; j
< C
; j
++ {
240 s1Ptr
= append(s1Ptr
, 0x77)
245 b
.Run("2Ptr", func(b
*testing
.B
) {
246 for i
:= 0; i
< b
.N
; i
++ {
247 s2Ptr
= make([][2]uintptr, C
)
248 for j
:= 0; j
< C
; j
++ {
249 s2Ptr
= append(s2Ptr
, [2]uintptr{0x77, 0x88})
254 b
.Run("3Ptr", func(b
*testing
.B
) {
255 for i
:= 0; i
< b
.N
; i
++ {
256 s3Ptr
= make([][3]uintptr, C
)
257 for j
:= 0; j
< C
; j
++ {
258 s3Ptr
= append(s3Ptr
, [3]uintptr{0x77, 0x88, 0x99})
263 b
.Run("4Ptr", func(b
*testing
.B
) {
264 for i
:= 0; i
< b
.N
; i
++ {
265 s4Ptr
= make([][4]uintptr, C
)
266 for j
:= 0; j
< C
; j
++ {
267 s4Ptr
= append(s4Ptr
, [4]uintptr{0x77, 0x88, 0x99, 0xAA})
274 b
.Run("Grow", func(b
*testing
.B
) {
277 b
.Run("Byte", func(b
*testing
.B
) {
278 for i
:= 0; i
< b
.N
; i
++ {
279 sByte
= make([]byte, 0)
280 for j
:= 0; j
< C
; j
++ {
281 sByte
= append(sByte
, 0x77)
282 sByte
= sByte
[:cap(sByte
)]
287 b
.Run("1Ptr", func(b
*testing
.B
) {
288 for i
:= 0; i
< b
.N
; i
++ {
289 s1Ptr
= make([]uintptr, 0)
290 for j
:= 0; j
< C
; j
++ {
291 s1Ptr
= append(s1Ptr
, 0x77)
292 s1Ptr
= s1Ptr
[:cap(s1Ptr
)]
297 b
.Run("2Ptr", func(b
*testing
.B
) {
298 for i
:= 0; i
< b
.N
; i
++ {
299 s2Ptr
= make([][2]uintptr, 0)
300 for j
:= 0; j
< C
; j
++ {
301 s2Ptr
= append(s2Ptr
, [2]uintptr{0x77, 0x88})
302 s2Ptr
= s2Ptr
[:cap(s2Ptr
)]
307 b
.Run("3Ptr", func(b
*testing
.B
) {
308 for i
:= 0; i
< b
.N
; i
++ {
309 s3Ptr
= make([][3]uintptr, 0)
310 for j
:= 0; j
< C
; j
++ {
311 s3Ptr
= append(s3Ptr
, [3]uintptr{0x77, 0x88, 0x99})
312 s3Ptr
= s3Ptr
[:cap(s3Ptr
)]
317 b
.Run("4Ptr", func(b
*testing
.B
) {
318 for i
:= 0; i
< b
.N
; i
++ {
319 s4Ptr
= make([][4]uintptr, 0)
320 for j
:= 0; j
< C
; j
++ {
321 s4Ptr
= append(s4Ptr
, [4]uintptr{0x77, 0x88, 0x99, 0xAA})
322 s4Ptr
= s4Ptr
[:cap(s4Ptr
)]