runtime: scan register backing store on ia64
[official-gcc.git] / libgo / go / runtime / append_test.go
blobef1e812c0dcfe6ea47f6ca6d08e08f1e99939787
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.
4 package runtime_test
6 import (
7 "fmt"
8 "testing"
11 const N = 20
13 func BenchmarkMakeSlice(b *testing.B) {
14 var x []byte
15 for i := 0; i < b.N; i++ {
16 x = make([]byte, 32)
17 _ = x
21 type (
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) {
29 x := make([]byte, 9)
30 for i := 0; i < b.N; i++ {
31 _ = append([]byte(nil), x...)
34 b.Run("Int", func(b *testing.B) {
35 x := make([]int, 9)
36 for i := 0; i < b.N; i++ {
37 _ = append([]int(nil), x...)
40 b.Run("Ptr", func(b *testing.B) {
41 x := make([]*byte, 9)
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) {
70 b.StopTimer()
71 x := make([]int, 0, N)
72 b.StartTimer()
73 for i := 0; i < b.N; i++ {
74 x = x[0:0]
75 for j := 0; j < N; j++ {
76 x = append(x, j)
81 func BenchmarkAppendGrowByte(b *testing.B) {
82 for i := 0; i < b.N; i++ {
83 var x []byte
84 for j := 0; j < 1<<20; j++ {
85 x = append(x, byte(j))
90 func BenchmarkAppendGrowString(b *testing.B) {
91 var s string
92 for i := 0; i < b.N; i++ {
93 var x []string
94 for j := 0; j < 1<<20; j++ {
95 x = append(x, s)
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++ {
106 x = x[0:0]
107 x = append(x, y...)
113 var (
114 blackhole []byte
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++ {
122 blackhole = nil
123 blackhole = append(blackhole, y...)
129 func BenchmarkAppendStr(b *testing.B) {
130 for _, str := range []string{
131 "1",
132 "1234",
133 "12345678",
134 "1234567890123456",
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++ {
140 x = x[0:0]
141 x = append(x, str...)
147 func BenchmarkAppendSpecialCase(b *testing.B) {
148 b.StopTimer()
149 x := make([]int, 0, N)
150 b.StartTimer()
151 for i := 0; i < b.N; i++ {
152 x = x[0:0]
153 for j := 0; j < N; j++ {
154 if len(x) < cap(x) {
155 x = x[:len(x)+1]
156 x[len(x)-1] = j
157 } else {
158 x = append(x, j)
164 var x []int
166 func f() int {
167 x[:1][0] = 3
168 return 2
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) {
180 x := []byte("1234")
181 x = append(x[1:], x...) // p > q in runtimeĀ·appendslice.
182 got := string(x)
183 want := "2341234"
184 if got != want {
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) {
193 s := make([]byte, l)
194 var n int
195 for i := 0; i < b.N; i++ {
196 n = copy(buf, s)
198 b.SetBytes(int64(n))
200 b.Run(fmt.Sprint(l, "String"), func(b *testing.B) {
201 s := string(make([]byte, l))
202 var n int
203 for i := 0; i < b.N; i++ {
204 n = copy(buf, s)
206 b.SetBytes(int64(n))
211 var (
212 sByte []byte
213 s1Ptr []uintptr
214 s2Ptr [][2]uintptr
215 s3Ptr [][3]uintptr
216 s4Ptr [][4]uintptr
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) {
235 const C = 128
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) {
285 const C = 5
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)]