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 5 6 import "testing" 7 8 const N = 20 9 10 func 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 22 func BenchmarkAppendGrowByte(b *testing.B) { 23 for i := 0; i < b.N; i++ { 24 var x []byte 25 for j := 0; j < 1<<20; j++ { 26 x = append(x, byte(j)) 27 } 28 } 29 } 30 31 func BenchmarkAppendGrowString(b *testing.B) { 32 var s string 33 for i := 0; i < b.N; i++ { 34 var x []string 35 for j := 0; j < 1<<20; j++ { 36 x = append(x, s) 37 } 38 } 39 } 40 41 func benchmarkAppendBytes(b *testing.B, length int) { 42 b.StopTimer() 43 x := make([]byte, 0, N) 44 y := make([]byte, length) 45 b.StartTimer() 46 for i := 0; i < b.N; i++ { 47 x = x[0:0] 48 x = append(x, y...) 49 } 50 } 51 52 func BenchmarkAppend1Byte(b *testing.B) { 53 benchmarkAppendBytes(b, 1) 54 } 55 56 func BenchmarkAppend4Bytes(b *testing.B) { 57 benchmarkAppendBytes(b, 4) 58 } 59 60 func BenchmarkAppend7Bytes(b *testing.B) { 61 benchmarkAppendBytes(b, 7) 62 } 63 64 func BenchmarkAppend8Bytes(b *testing.B) { 65 benchmarkAppendBytes(b, 8) 66 } 67 68 func BenchmarkAppend15Bytes(b *testing.B) { 69 benchmarkAppendBytes(b, 15) 70 } 71 72 func BenchmarkAppend16Bytes(b *testing.B) { 73 benchmarkAppendBytes(b, 16) 74 } 75 76 func BenchmarkAppend32Bytes(b *testing.B) { 77 benchmarkAppendBytes(b, 32) 78 } 79 80 func benchmarkAppendStr(b *testing.B, str string) { 81 b.StopTimer() 82 x := make([]byte, 0, N) 83 b.StartTimer() 84 for i := 0; i < b.N; i++ { 85 x = x[0:0] 86 x = append(x, str...) 87 } 88 } 89 90 func BenchmarkAppendStr1Byte(b *testing.B) { 91 benchmarkAppendStr(b, "1") 92 } 93 94 func BenchmarkAppendStr4Bytes(b *testing.B) { 95 benchmarkAppendStr(b, "1234") 96 } 97 98 func BenchmarkAppendStr8Bytes(b *testing.B) { 99 benchmarkAppendStr(b, "12345678") 100 } 101 102 func BenchmarkAppendStr16Bytes(b *testing.B) { 103 benchmarkAppendStr(b, "1234567890123456") 104 } 105 106 func BenchmarkAppendStr32Bytes(b *testing.B) { 107 benchmarkAppendStr(b, "12345678901234567890123456789012") 108 } 109 110 func BenchmarkAppendSpecialCase(b *testing.B) { 111 b.StopTimer() 112 x := make([]int, 0, N) 113 b.StartTimer() 114 for i := 0; i < b.N; i++ { 115 x = x[0:0] 116 for j := 0; j < N; j++ { 117 if len(x) < cap(x) { 118 x = x[:len(x)+1] 119 x[len(x)-1] = j 120 } else { 121 x = append(x, j) 122 } 123 } 124 } 125 } 126 127 var x []int 128 129 func f() int { 130 x[:1][0] = 3 131 return 2 132 } 133 134 func TestSideEffectOrder(t *testing.T) { 135 x = make([]int, 0, 10) 136 x = append(x, 1, f()) 137 if x[0] != 1 || x[1] != 2 { 138 t.Error("append failed: ", x[0], x[1]) 139 } 140 } 141 142 func TestAppendOverlap(t *testing.T) { 143 x := []byte("1234") 144 x = append(x[1:], x...) // p > q in runtimeappendslice. 145 got := string(x) 146 want := "2341234" 147 if got != want { 148 t.Errorf("overlap failed: got %q want %q", got, want) 149 } 150 } 151 152 func benchmarkCopySlice(b *testing.B, l int) { 153 s := make([]byte, l) 154 buf := make([]byte, 4096) 155 var n int 156 for i := 0; i < b.N; i++ { 157 n = copy(buf, s) 158 } 159 b.SetBytes(int64(n)) 160 } 161 162 func benchmarkCopyStr(b *testing.B, l int) { 163 s := string(make([]byte, l)) 164 buf := make([]byte, 4096) 165 var n int 166 for i := 0; i < b.N; i++ { 167 n = copy(buf, s) 168 } 169 b.SetBytes(int64(n)) 170 } 171 172 func BenchmarkCopy1Byte(b *testing.B) { benchmarkCopySlice(b, 1) } 173 func BenchmarkCopy2Byte(b *testing.B) { benchmarkCopySlice(b, 2) } 174 func BenchmarkCopy4Byte(b *testing.B) { benchmarkCopySlice(b, 4) } 175 func BenchmarkCopy8Byte(b *testing.B) { benchmarkCopySlice(b, 8) } 176 func BenchmarkCopy12Byte(b *testing.B) { benchmarkCopySlice(b, 12) } 177 func BenchmarkCopy16Byte(b *testing.B) { benchmarkCopySlice(b, 16) } 178 func BenchmarkCopy32Byte(b *testing.B) { benchmarkCopySlice(b, 32) } 179 func BenchmarkCopy128Byte(b *testing.B) { benchmarkCopySlice(b, 128) } 180 func BenchmarkCopy1024Byte(b *testing.B) { benchmarkCopySlice(b, 1024) } 181 182 func BenchmarkCopy1String(b *testing.B) { benchmarkCopyStr(b, 1) } 183 func BenchmarkCopy2String(b *testing.B) { benchmarkCopyStr(b, 2) } 184 func BenchmarkCopy4String(b *testing.B) { benchmarkCopyStr(b, 4) } 185 func BenchmarkCopy8String(b *testing.B) { benchmarkCopyStr(b, 8) } 186 func BenchmarkCopy12String(b *testing.B) { benchmarkCopyStr(b, 12) } 187 func BenchmarkCopy16String(b *testing.B) { benchmarkCopyStr(b, 16) } 188 func BenchmarkCopy32String(b *testing.B) { benchmarkCopyStr(b, 32) } 189 func BenchmarkCopy128String(b *testing.B) { benchmarkCopyStr(b, 128) } 190 func BenchmarkCopy1024String(b *testing.B) { benchmarkCopyStr(b, 1024) } 191