Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 

253 Zeilen
5.2 KiB

  1. // Copyright 2014 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package btree
  15. import (
  16. "fmt"
  17. "sort"
  18. "testing"
  19. )
  20. const benchmarkTreeSize = 10000
  21. var degrees = []int{2, 8, 32, 64}
  22. func BenchmarkInsert(b *testing.B) {
  23. insertP := perm(benchmarkTreeSize)
  24. for _, d := range degrees {
  25. b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
  26. i := 0
  27. for i < b.N {
  28. tr := New(d, less)
  29. for _, m := range insertP {
  30. tr.Set(m.Key, m.Value)
  31. i++
  32. if i >= b.N {
  33. return
  34. }
  35. }
  36. }
  37. })
  38. }
  39. }
  40. func BenchmarkDeleteInsert(b *testing.B) {
  41. insertP := perm(benchmarkTreeSize)
  42. for _, d := range degrees {
  43. b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
  44. tr := New(d, less)
  45. for _, m := range insertP {
  46. tr.Set(m.Key, m.Value)
  47. }
  48. b.ResetTimer()
  49. for i := 0; i < b.N; i++ {
  50. m := insertP[i%benchmarkTreeSize]
  51. tr.Delete(m.Key)
  52. tr.Set(m.Key, m.Value)
  53. }
  54. })
  55. }
  56. }
  57. func BenchmarkDeleteInsertCloneOnce(b *testing.B) {
  58. insertP := perm(benchmarkTreeSize)
  59. for _, d := range degrees {
  60. b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
  61. tr := New(d, less)
  62. for _, m := range insertP {
  63. tr.Set(m.Key, m.Value)
  64. }
  65. tr = tr.Clone()
  66. b.ResetTimer()
  67. for i := 0; i < b.N; i++ {
  68. m := insertP[i%benchmarkTreeSize]
  69. tr.Delete(m.Key)
  70. tr.Set(m.Key, m.Value)
  71. }
  72. })
  73. }
  74. }
  75. func BenchmarkDeleteInsertCloneEachTime(b *testing.B) {
  76. insertP := perm(benchmarkTreeSize)
  77. for _, d := range degrees {
  78. b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
  79. tr := New(d, less)
  80. for _, m := range insertP {
  81. tr.Set(m.Key, m.Value)
  82. }
  83. b.ResetTimer()
  84. for i := 0; i < b.N; i++ {
  85. tr = tr.Clone()
  86. m := insertP[i%benchmarkTreeSize]
  87. tr.Delete(m.Key)
  88. tr.Set(m.Key, m.Value)
  89. }
  90. })
  91. }
  92. }
  93. func BenchmarkDelete(b *testing.B) {
  94. insertP := perm(benchmarkTreeSize)
  95. removeP := perm(benchmarkTreeSize)
  96. for _, d := range degrees {
  97. b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
  98. i := 0
  99. for i < b.N {
  100. b.StopTimer()
  101. tr := New(d, less)
  102. for _, v := range insertP {
  103. tr.Set(v.Key, v.Value)
  104. }
  105. b.StartTimer()
  106. for _, m := range removeP {
  107. tr.Delete(m.Key)
  108. i++
  109. if i >= b.N {
  110. return
  111. }
  112. }
  113. if tr.Len() > 0 {
  114. panic(tr.Len())
  115. }
  116. }
  117. })
  118. }
  119. }
  120. func BenchmarkGet(b *testing.B) {
  121. insertP := perm(benchmarkTreeSize)
  122. getP := perm(benchmarkTreeSize)
  123. for _, d := range degrees {
  124. b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
  125. i := 0
  126. for i < b.N {
  127. b.StopTimer()
  128. tr := New(d, less)
  129. for _, v := range insertP {
  130. tr.Set(v.Key, v.Value)
  131. }
  132. b.StartTimer()
  133. for _, m := range getP {
  134. tr.Get(m.Key)
  135. i++
  136. if i >= b.N {
  137. return
  138. }
  139. }
  140. }
  141. })
  142. }
  143. }
  144. func BenchmarkGetWithIndex(b *testing.B) {
  145. insertP := perm(benchmarkTreeSize)
  146. getP := perm(benchmarkTreeSize)
  147. for _, d := range degrees {
  148. b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
  149. i := 0
  150. for i < b.N {
  151. b.StopTimer()
  152. tr := New(d, less)
  153. for _, v := range insertP {
  154. tr.Set(v.Key, v.Value)
  155. }
  156. b.StartTimer()
  157. for _, m := range getP {
  158. tr.GetWithIndex(m.Key)
  159. i++
  160. if i >= b.N {
  161. return
  162. }
  163. }
  164. }
  165. })
  166. }
  167. }
  168. func BenchmarkGetCloneEachTime(b *testing.B) {
  169. insertP := perm(benchmarkTreeSize)
  170. getP := perm(benchmarkTreeSize)
  171. for _, d := range degrees {
  172. b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
  173. i := 0
  174. for i < b.N {
  175. b.StopTimer()
  176. tr := New(d, less)
  177. for _, m := range insertP {
  178. tr.Set(m.Key, m.Value)
  179. }
  180. b.StartTimer()
  181. for _, m := range getP {
  182. tr = tr.Clone()
  183. tr.Get(m.Key)
  184. i++
  185. if i >= b.N {
  186. return
  187. }
  188. }
  189. }
  190. })
  191. }
  192. }
  193. func BenchmarkFind(b *testing.B) {
  194. for _, d := range degrees {
  195. var items []item
  196. for i := 0; i < 2*d; i++ {
  197. items = append(items, item{i, i})
  198. }
  199. b.Run(fmt.Sprintf("size=%d", len(items)), func(b *testing.B) {
  200. for _, alg := range []struct {
  201. name string
  202. fun func(Key, []item) (int, bool)
  203. }{
  204. {"binary", findBinary},
  205. {"linear", findLinear},
  206. } {
  207. b.Run(alg.name, func(b *testing.B) {
  208. for i := 0; i < b.N; i++ {
  209. for j := 0; j < len(items); j++ {
  210. alg.fun(items[j].key, items)
  211. }
  212. }
  213. })
  214. }
  215. })
  216. }
  217. }
  218. func findBinary(k Key, s []item) (int, bool) {
  219. i := sort.Search(len(s), func(i int) bool { return less(k, s[i].key) })
  220. // i is the smallest index of s for which key.Less(s[i].Key), or len(s).
  221. if i > 0 && !less(s[i-1], k) {
  222. return i - 1, true
  223. }
  224. return i, false
  225. }
  226. func findLinear(k Key, s []item) (int, bool) {
  227. var i int
  228. for i = 0; i < len(s); i++ {
  229. if less(k, s[i].key) {
  230. break
  231. }
  232. }
  233. if i > 0 && !less(s[i-1].key, k) {
  234. return i - 1, true
  235. }
  236. return i, false
  237. }