append_test.go 4.4 KB

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