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.
4package runtime_test
5
6import "testing"
7
8const N = 20
9
10func BenchmarkAppend(b *testing.B) {
11	b.StopTimer()
12	x := make([]int, 0, N)
13	b.StartTimer()
14	for i := 0; i < b.N; i++ {
15		x = x[0:0]
16		for j := 0; j < N; j++ {
17			x = append(x, j)
18		}
19	}
20}
21
22func benchmarkAppendBytes(b *testing.B, length int) {
23	b.StopTimer()
24	x := make([]byte, 0, N)
25	y := make([]byte, length)
26	b.StartTimer()
27	for i := 0; i < b.N; i++ {
28		x = x[0:0]
29		x = append(x, y...)
30	}
31}
32
33func BenchmarkAppend1Byte(b *testing.B) {
34	benchmarkAppendBytes(b, 1)
35}
36
37func BenchmarkAppend4Bytes(b *testing.B) {
38	benchmarkAppendBytes(b, 4)
39}
40
41func BenchmarkAppend8Bytes(b *testing.B) {
42	benchmarkAppendBytes(b, 8)
43}
44
45func BenchmarkAppend16Bytes(b *testing.B) {
46	benchmarkAppendBytes(b, 16)
47}
48
49func BenchmarkAppend32Bytes(b *testing.B) {
50	benchmarkAppendBytes(b, 32)
51}
52
53func benchmarkAppendStr(b *testing.B, str string) {
54	b.StopTimer()
55	x := make([]byte, 0, N)
56	b.StartTimer()
57	for i := 0; i < b.N; i++ {
58		x = x[0:0]
59		x = append(x, str...)
60	}
61}
62
63func BenchmarkAppendStr1Byte(b *testing.B) {
64	benchmarkAppendStr(b, "1")
65}
66
67func BenchmarkAppendStr4Bytes(b *testing.B) {
68	benchmarkAppendStr(b, "1234")
69}
70
71func BenchmarkAppendStr8Bytes(b *testing.B) {
72	benchmarkAppendStr(b, "12345678")
73}
74
75func BenchmarkAppendStr16Bytes(b *testing.B) {
76	benchmarkAppendStr(b, "1234567890123456")
77}
78
79func BenchmarkAppendStr32Bytes(b *testing.B) {
80	benchmarkAppendStr(b, "12345678901234567890123456789012")
81}
82
83func BenchmarkAppendSpecialCase(b *testing.B) {
84	b.StopTimer()
85	x := make([]int, 0, N)
86	b.StartTimer()
87	for i := 0; i < b.N; i++ {
88		x = x[0:0]
89		for j := 0; j < N; j++ {
90			if len(x) < cap(x) {
91				x = x[:len(x)+1]
92				x[len(x)-1] = j
93			} else {
94				x = append(x, j)
95			}
96		}
97	}
98}
99
100var x []int
101
102func f() int {
103	x[:1][0] = 3
104	return 2
105}
106
107func TestSideEffectOrder(t *testing.T) {
108	x = make([]int, 0, 10)
109	x = append(x, 1, f())
110	if x[0] != 1 || x[1] != 2 {
111		t.Error("append failed: ", x[0], x[1])
112	}
113}
114
115func TestAppendOverlap(t *testing.T) {
116	x := []byte("1234")
117	x = append(x[1:], x...) // p > q in runtime·appendslice.
118	got := string(x)
119	want := "2341234"
120	if got != want {
121		t.Errorf("overlap failed: got %q want %q", got, want)
122	}
123}
124