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
++ {
22 struct24
struct{ a
, b
, c
int64 }
23 struct32
struct{ a
, b
, c
, d
int64 }
24 struct40
struct{ a
, b
, c
, d
, e
int64 }
27 func BenchmarkGrowSlice(b
*testing
.B
) {
28 b
.Run("Byte", func(b
*testing
.B
) {
30 for i
:= 0; i
< b
.N
; i
++ {
31 _
= append([]byte(nil), x
...)
34 b
.Run("Int", func(b
*testing
.B
) {
36 for i
:= 0; i
< b
.N
; i
++ {
37 _
= append([]int(nil), x
...)
40 b
.Run("Ptr", func(b
*testing
.B
) {
42 for i
:= 0; i
< b
.N
; i
++ {
43 _
= append([]*byte(nil), x
...)
46 b
.Run("Struct", func(b
*testing
.B
) {
47 b
.Run("24", func(b
*testing
.B
) {
48 x
:= make([]struct24
, 9)
49 for i
:= 0; i
< b
.N
; i
++ {
50 _
= append([]struct24(nil), x
...)
53 b
.Run("32", func(b
*testing
.B
) {
54 x
:= make([]struct32
, 9)
55 for i
:= 0; i
< b
.N
; i
++ {
56 _
= append([]struct32(nil), x
...)
59 b
.Run("40", func(b
*testing
.B
) {
60 x
:= make([]struct40
, 9)
61 for i
:= 0; i
< b
.N
; i
++ {
62 _
= append([]struct40(nil), x
...)
69 func BenchmarkAppend(b
*testing
.B
) {
71 x
:= make([]int, 0, N
)
73 for i
:= 0; i
< b
.N
; i
++ {
75 for j
:= 0; j
< N
; j
++ {
81 func BenchmarkAppendGrowByte(b
*testing
.B
) {
82 for i
:= 0; i
< b
.N
; i
++ {
84 for j
:= 0; j
< 1<<20; j
++ {
85 x
= append(x
, byte(j
))
90 func BenchmarkAppendGrowString(b
*testing
.B
) {
92 for i
:= 0; i
< b
.N
; i
++ {
94 for j
:= 0; j
< 1<<20; j
++ {
100 func BenchmarkAppendSlice(b
*testing
.B
) {
101 for _
, length
:= range []int{1, 4, 7, 8, 15, 16, 32} {
102 b
.Run(fmt
.Sprint(length
, "Bytes"), func(b
*testing
.B
) {
103 x
:= make([]byte, 0, N
)
104 y
:= make([]byte, length
)
105 for i
:= 0; i
< b
.N
; i
++ {
117 func BenchmarkAppendSliceLarge(b
*testing
.B
) {
118 for _
, length
:= range []int{1 << 10, 4 << 10, 16 << 10, 64 << 10, 256 << 10, 1024 << 10} {
119 y
:= make([]byte, length
)
120 b
.Run(fmt
.Sprint(length
, "Bytes"), func(b
*testing
.B
) {
121 for i
:= 0; i
< b
.N
; i
++ {
123 blackhole
= append(blackhole
, y
...)
129 func BenchmarkAppendStr(b
*testing
.B
) {
130 for _
, str
:= range []string{
135 "12345678901234567890123456789012",
137 b
.Run(fmt
.Sprint(len(str
), "Bytes"), func(b
*testing
.B
) {
138 x
:= make([]byte, 0, N
)
139 for i
:= 0; i
< b
.N
; i
++ {
141 x
= append(x
, str
...)
147 func BenchmarkAppendSpecialCase(b
*testing
.B
) {
149 x
:= make([]int, 0, N
)
151 for i
:= 0; i
< b
.N
; i
++ {
153 for j
:= 0; j
< N
; j
++ {
171 func TestSideEffectOrder(t
*testing
.T
) {
172 x
= make([]int, 0, 10)
173 x
= append(x
, 1, f())
174 if x
[0] != 1 || x
[1] != 2 {
175 t
.Error("append failed: ", x
[0], x
[1])
179 func TestAppendOverlap(t
*testing
.T
) {
181 x
= append(x
[1:], x
...) // p > q in runtimeĀ·appendslice.
185 t
.Errorf("overlap failed: got %q want %q", got
, want
)
189 func BenchmarkCopy(b
*testing
.B
) {
190 for _
, l
:= range []int{1, 2, 4, 8, 12, 16, 32, 128, 1024} {
191 buf
:= make([]byte, 4096)
192 b
.Run(fmt
.Sprint(l
, "Byte"), func(b
*testing
.B
) {
195 for i
:= 0; i
< b
.N
; i
++ {
200 b
.Run(fmt
.Sprint(l
, "String"), func(b
*testing
.B
) {
201 s
:= string(make([]byte, l
))
203 for i
:= 0; i
< b
.N
; i
++ {
219 // BenchmarkAppendInPlace tests the performance of append
220 // when the result is being written back to the same slice.
221 // In order for the in-place optimization to occur,
222 // the slice must be referred to by address;
223 // using a global is an easy way to trigger that.
224 // We test the "grow" and "no grow" paths separately,
225 // but not the "normal" (occasionally grow) path,
226 // because it is a blend of the other two.
227 // We use small numbers and small sizes in an attempt
228 // to avoid benchmarking memory allocation and copying.
229 // We use scalars instead of pointers in an attempt
230 // to avoid benchmarking the write barriers.
231 // We benchmark four common sizes (byte, pointer, string/interface, slice),
232 // and one larger size.
233 func BenchmarkAppendInPlace(b
*testing
.B
) {
234 b
.Run("NoGrow", func(b
*testing
.B
) {
237 b
.Run("Byte", func(b
*testing
.B
) {
238 for i
:= 0; i
< b
.N
; i
++ {
239 sByte
= make([]byte, C
)
240 for j
:= 0; j
< C
; j
++ {
241 sByte
= append(sByte
, 0x77)
246 b
.Run("1Ptr", func(b
*testing
.B
) {
247 for i
:= 0; i
< b
.N
; i
++ {
248 s1Ptr
= make([]uintptr, C
)
249 for j
:= 0; j
< C
; j
++ {
250 s1Ptr
= append(s1Ptr
, 0x77)
255 b
.Run("2Ptr", func(b
*testing
.B
) {
256 for i
:= 0; i
< b
.N
; i
++ {
257 s2Ptr
= make([][2]uintptr, C
)
258 for j
:= 0; j
< C
; j
++ {
259 s2Ptr
= append(s2Ptr
, [2]uintptr{0x77, 0x88})
264 b
.Run("3Ptr", func(b
*testing
.B
) {
265 for i
:= 0; i
< b
.N
; i
++ {
266 s3Ptr
= make([][3]uintptr, C
)
267 for j
:= 0; j
< C
; j
++ {
268 s3Ptr
= append(s3Ptr
, [3]uintptr{0x77, 0x88, 0x99})
273 b
.Run("4Ptr", func(b
*testing
.B
) {
274 for i
:= 0; i
< b
.N
; i
++ {
275 s4Ptr
= make([][4]uintptr, C
)
276 for j
:= 0; j
< C
; j
++ {
277 s4Ptr
= append(s4Ptr
, [4]uintptr{0x77, 0x88, 0x99, 0xAA})
284 b
.Run("Grow", func(b
*testing
.B
) {
287 b
.Run("Byte", func(b
*testing
.B
) {
288 for i
:= 0; i
< b
.N
; i
++ {
289 sByte
= make([]byte, 0)
290 for j
:= 0; j
< C
; j
++ {
291 sByte
= append(sByte
, 0x77)
292 sByte
= sByte
[:cap(sByte
)]
297 b
.Run("1Ptr", func(b
*testing
.B
) {
298 for i
:= 0; i
< b
.N
; i
++ {
299 s1Ptr
= make([]uintptr, 0)
300 for j
:= 0; j
< C
; j
++ {
301 s1Ptr
= append(s1Ptr
, 0x77)
302 s1Ptr
= s1Ptr
[:cap(s1Ptr
)]
307 b
.Run("2Ptr", func(b
*testing
.B
) {
308 for i
:= 0; i
< b
.N
; i
++ {
309 s2Ptr
= make([][2]uintptr, 0)
310 for j
:= 0; j
< C
; j
++ {
311 s2Ptr
= append(s2Ptr
, [2]uintptr{0x77, 0x88})
312 s2Ptr
= s2Ptr
[:cap(s2Ptr
)]
317 b
.Run("3Ptr", func(b
*testing
.B
) {
318 for i
:= 0; i
< b
.N
; i
++ {
319 s3Ptr
= make([][3]uintptr, 0)
320 for j
:= 0; j
< C
; j
++ {
321 s3Ptr
= append(s3Ptr
, [3]uintptr{0x77, 0x88, 0x99})
322 s3Ptr
= s3Ptr
[:cap(s3Ptr
)]
327 b
.Run("4Ptr", func(b
*testing
.B
) {
328 for i
:= 0; i
< b
.N
; i
++ {
329 s4Ptr
= make([][4]uintptr, 0)
330 for j
:= 0; j
< C
; j
++ {
331 s4Ptr
= append(s4Ptr
, [4]uintptr{0x77, 0x88, 0x99, 0xAA})
332 s4Ptr
= s4Ptr
[:cap(s4Ptr
)]