選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 

269 行
5.4 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. // +build go1.7
  15. package btree
  16. import (
  17. "fmt"
  18. "sort"
  19. "testing"
  20. )
  21. const benchmarkTreeSize = 10000
  22. var degrees = []int{2, 8, 32, 64}
  23. func BenchmarkInsert(b *testing.B) {
  24. insertP := perm(benchmarkTreeSize)
  25. for _, d := range degrees {
  26. b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
  27. i := 0
  28. for i < b.N {
  29. tr := New(d, less)
  30. for _, m := range insertP {
  31. tr.Set(m.Key, m.Value)
  32. i++
  33. if i >= b.N {
  34. return
  35. }
  36. }
  37. }
  38. })
  39. }
  40. }
  41. func BenchmarkDeleteInsert(b *testing.B) {
  42. insertP := perm(benchmarkTreeSize)
  43. for _, d := range degrees {
  44. b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
  45. tr := New(d, less)
  46. for _, m := range insertP {
  47. tr.Set(m.Key, m.Value)
  48. }
  49. b.ResetTimer()
  50. for i := 0; i < b.N; i++ {
  51. m := insertP[i%benchmarkTreeSize]
  52. tr.Delete(m.Key)
  53. tr.Set(m.Key, m.Value)
  54. }
  55. })
  56. }
  57. }
  58. func BenchmarkDeleteInsertCloneOnce(b *testing.B) {
  59. insertP := perm(benchmarkTreeSize)
  60. for _, d := range degrees {
  61. b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
  62. tr := New(d, less)
  63. for _, m := range insertP {
  64. tr.Set(m.Key, m.Value)
  65. }
  66. tr = tr.Clone()
  67. b.ResetTimer()
  68. for i := 0; i < b.N; i++ {
  69. m := insertP[i%benchmarkTreeSize]
  70. tr.Delete(m.Key)
  71. tr.Set(m.Key, m.Value)
  72. }
  73. })
  74. }
  75. }
  76. func BenchmarkDeleteInsertCloneEachTime(b *testing.B) {
  77. insertP := perm(benchmarkTreeSize)
  78. for _, d := range degrees {
  79. b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
  80. tr := New(d, less)
  81. for _, m := range insertP {
  82. tr.Set(m.Key, m.Value)
  83. }
  84. b.ResetTimer()
  85. for i := 0; i < b.N; i++ {
  86. tr = tr.Clone()
  87. m := insertP[i%benchmarkTreeSize]
  88. tr.Delete(m.Key)
  89. tr.Set(m.Key, m.Value)
  90. }
  91. })
  92. }
  93. }
  94. func BenchmarkDelete(b *testing.B) {
  95. insertP := perm(benchmarkTreeSize)
  96. removeP := perm(benchmarkTreeSize)
  97. for _, d := range degrees {
  98. b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
  99. i := 0
  100. for i < b.N {
  101. b.StopTimer()
  102. tr := New(d, less)
  103. for _, v := range insertP {
  104. tr.Set(v.Key, v.Value)
  105. }
  106. b.StartTimer()
  107. for _, m := range removeP {
  108. tr.Delete(m.Key)
  109. i++
  110. if i >= b.N {
  111. return
  112. }
  113. }
  114. if tr.Len() > 0 {
  115. panic(tr.Len())
  116. }
  117. }
  118. })
  119. }
  120. }
  121. func BenchmarkGet(b *testing.B) {
  122. insertP := perm(benchmarkTreeSize)
  123. getP := perm(benchmarkTreeSize)
  124. for _, d := range degrees {
  125. b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
  126. i := 0
  127. for i < b.N {
  128. b.StopTimer()
  129. tr := New(d, less)
  130. for _, v := range insertP {
  131. tr.Set(v.Key, v.Value)
  132. }
  133. b.StartTimer()
  134. for _, m := range getP {
  135. tr.Get(m.Key)
  136. i++
  137. if i >= b.N {
  138. return
  139. }
  140. }
  141. }
  142. })
  143. }
  144. }
  145. func BenchmarkGetWithIndex(b *testing.B) {
  146. insertP := perm(benchmarkTreeSize)
  147. getP := perm(benchmarkTreeSize)
  148. for _, d := range degrees {
  149. b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
  150. i := 0
  151. for i < b.N {
  152. b.StopTimer()
  153. tr := New(d, less)
  154. for _, v := range insertP {
  155. tr.Set(v.Key, v.Value)
  156. }
  157. b.StartTimer()
  158. for _, m := range getP {
  159. tr.GetWithIndex(m.Key)
  160. i++
  161. if i >= b.N {
  162. return
  163. }
  164. }
  165. }
  166. })
  167. }
  168. }
  169. func BenchmarkGetCloneEachTime(b *testing.B) {
  170. insertP := perm(benchmarkTreeSize)
  171. getP := perm(benchmarkTreeSize)
  172. for _, d := range degrees {
  173. b.Run(fmt.Sprintf("degree=%d", d), func(b *testing.B) {
  174. i := 0
  175. for i < b.N {
  176. b.StopTimer()
  177. tr := New(d, less)
  178. for _, m := range insertP {
  179. tr.Set(m.Key, m.Value)
  180. }
  181. b.StartTimer()
  182. for _, m := range getP {
  183. tr = tr.Clone()
  184. tr.Get(m.Key)
  185. i++
  186. if i >= b.N {
  187. return
  188. }
  189. }
  190. }
  191. })
  192. }
  193. }
  194. func BenchmarkFind(b *testing.B) {
  195. for _, d := range degrees {
  196. var items []item
  197. for i := 0; i < 2*d; i++ {
  198. items = append(items, item{i, i})
  199. }
  200. b.Run(fmt.Sprintf("size=%d", len(items)), func(b *testing.B) {
  201. for _, alg := range []struct {
  202. name string
  203. fun func(Key, []item) (int, bool)
  204. }{
  205. {"binary", findBinary},
  206. {"linear", findLinear},
  207. } {
  208. b.Run(alg.name, func(b *testing.B) {
  209. for i := 0; i < b.N; i++ {
  210. for j := 0; j < len(items); j++ {
  211. alg.fun(items[j].key, items)
  212. }
  213. }
  214. })
  215. }
  216. })
  217. }
  218. }
  219. func findBinary(k Key, s []item) (int, bool) {
  220. i := sort.Search(len(s), func(i int) bool { return less(k, s[i].key) })
  221. // i is the smallest index of s for which key.Less(s[i].Key), or len(s).
  222. if i > 0 && !less(s[i-1], k) {
  223. return i - 1, true
  224. }
  225. return i, false
  226. }
  227. func findLinear(k Key, s []item) (int, bool) {
  228. var i int
  229. for i = 0; i < len(s); i++ {
  230. if less(k, s[i].key) {
  231. break
  232. }
  233. }
  234. if i > 0 && !less(s[i-1].key, k) {
  235. return i - 1, true
  236. }
  237. return i, false
  238. }
  239. type byInts []item
  240. func (a byInts) Len() int {
  241. return len(a)
  242. }
  243. func (a byInts) Less(i, j int) bool {
  244. return a[i].key.(int) < a[j].key.(int)
  245. }
  246. func (a byInts) Swap(i, j int) {
  247. a[i], a[j] = a[j], a[i]
  248. }