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
++ {
103 func BenchmarkAppendStr(b
*testing
.B
) {
104 for _
, str
:= range []string{
109 "12345678901234567890123456789012",
111 b
.Run(fmt
.Sprint(len(str
), "Bytes"), func(b
*testing
.B
) {
112 x
:= make([]byte, 0, N
)
113 for i
:= 0; i
< b
.N
; i
++ {
115 x
= append(x
, str
...)
121 func BenchmarkAppendSpecialCase(b
*testing
.B
) {
123 x
:= make([]int, 0, N
)
125 for i
:= 0; i
< b
.N
; i
++ {
127 for j
:= 0; j
< N
; j
++ {
145 func TestSideEffectOrder(t
*testing
.T
) {
146 x
= make([]int, 0, 10)
147 x
= append(x
, 1, f())
148 if x
[0] != 1 || x
[1] != 2 {
149 t
.Error("append failed: ", x
[0], x
[1])
153 func TestAppendOverlap(t
*testing
.T
) {
155 x
= append(x
[1:], x
...) // p > q in runtimeĀ·appendslice.
159 t
.Errorf("overlap failed: got %q want %q", got
, want
)
163 func BenchmarkCopy(b
*testing
.B
) {
164 for _
, l
:= range []int{1, 2, 4, 8, 12, 16, 32, 128, 1024} {
165 buf
:= make([]byte, 4096)
166 b
.Run(fmt
.Sprint(l
, "Byte"), func(b
*testing
.B
) {
169 for i
:= 0; i
< b
.N
; i
++ {
174 b
.Run(fmt
.Sprint(l
, "String"), func(b
*testing
.B
) {
175 s
:= string(make([]byte, l
))
177 for i
:= 0; i
< b
.N
; i
++ {
193 // BenchmarkAppendInPlace tests the performance of append
194 // when the result is being written back to the same slice.
195 // In order for the in-place optimization to occur,
196 // the slice must be referred to by address;
197 // using a global is an easy way to trigger that.
198 // We test the "grow" and "no grow" paths separately,
199 // but not the "normal" (occasionally grow) path,
200 // because it is a blend of the other two.
201 // We use small numbers and small sizes in an attempt
202 // to avoid benchmarking memory allocation and copying.
203 // We use scalars instead of pointers in an attempt
204 // to avoid benchmarking the write barriers.
205 // We benchmark four common sizes (byte, pointer, string/interface, slice),
206 // and one larger size.
207 func BenchmarkAppendInPlace(b
*testing
.B
) {
208 b
.Run("NoGrow", func(b
*testing
.B
) {
211 b
.Run("Byte", func(b
*testing
.B
) {
212 for i
:= 0; i
< b
.N
; i
++ {
213 sByte
= make([]byte, C
)
214 for j
:= 0; j
< C
; j
++ {
215 sByte
= append(sByte
, 0x77)
220 b
.Run("1Ptr", func(b
*testing
.B
) {
221 for i
:= 0; i
< b
.N
; i
++ {
222 s1Ptr
= make([]uintptr, C
)
223 for j
:= 0; j
< C
; j
++ {
224 s1Ptr
= append(s1Ptr
, 0x77)
229 b
.Run("2Ptr", func(b
*testing
.B
) {
230 for i
:= 0; i
< b
.N
; i
++ {
231 s2Ptr
= make([][2]uintptr, C
)
232 for j
:= 0; j
< C
; j
++ {
233 s2Ptr
= append(s2Ptr
, [2]uintptr{0x77, 0x88})
238 b
.Run("3Ptr", func(b
*testing
.B
) {
239 for i
:= 0; i
< b
.N
; i
++ {
240 s3Ptr
= make([][3]uintptr, C
)
241 for j
:= 0; j
< C
; j
++ {
242 s3Ptr
= append(s3Ptr
, [3]uintptr{0x77, 0x88, 0x99})
247 b
.Run("4Ptr", func(b
*testing
.B
) {
248 for i
:= 0; i
< b
.N
; i
++ {
249 s4Ptr
= make([][4]uintptr, C
)
250 for j
:= 0; j
< C
; j
++ {
251 s4Ptr
= append(s4Ptr
, [4]uintptr{0x77, 0x88, 0x99, 0xAA})
258 b
.Run("Grow", func(b
*testing
.B
) {
261 b
.Run("Byte", func(b
*testing
.B
) {
262 for i
:= 0; i
< b
.N
; i
++ {
263 sByte
= make([]byte, 0)
264 for j
:= 0; j
< C
; j
++ {
265 sByte
= append(sByte
, 0x77)
266 sByte
= sByte
[:cap(sByte
)]
271 b
.Run("1Ptr", func(b
*testing
.B
) {
272 for i
:= 0; i
< b
.N
; i
++ {
273 s1Ptr
= make([]uintptr, 0)
274 for j
:= 0; j
< C
; j
++ {
275 s1Ptr
= append(s1Ptr
, 0x77)
276 s1Ptr
= s1Ptr
[:cap(s1Ptr
)]
281 b
.Run("2Ptr", func(b
*testing
.B
) {
282 for i
:= 0; i
< b
.N
; i
++ {
283 s2Ptr
= make([][2]uintptr, 0)
284 for j
:= 0; j
< C
; j
++ {
285 s2Ptr
= append(s2Ptr
, [2]uintptr{0x77, 0x88})
286 s2Ptr
= s2Ptr
[:cap(s2Ptr
)]
291 b
.Run("3Ptr", func(b
*testing
.B
) {
292 for i
:= 0; i
< b
.N
; i
++ {
293 s3Ptr
= make([][3]uintptr, 0)
294 for j
:= 0; j
< C
; j
++ {
295 s3Ptr
= append(s3Ptr
, [3]uintptr{0x77, 0x88, 0x99})
296 s3Ptr
= s3Ptr
[:cap(s3Ptr
)]
301 b
.Run("4Ptr", func(b
*testing
.B
) {
302 for i
:= 0; i
< b
.N
; i
++ {
303 s4Ptr
= make([][4]uintptr, 0)
304 for j
:= 0; j
< C
; j
++ {
305 s4Ptr
= append(s4Ptr
, [4]uintptr{0x77, 0x88, 0x99, 0xAA})
306 s4Ptr
= s4Ptr
[:cap(s4Ptr
)]