store_bench_test.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. // Copyright 2015 The etcd Authors
  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 store
  15. import (
  16. "encoding/json"
  17. "fmt"
  18. "runtime"
  19. "testing"
  20. )
  21. func BenchmarkStoreSet128Bytes(b *testing.B) {
  22. benchStoreSet(b, 128, nil)
  23. }
  24. func BenchmarkStoreSet1024Bytes(b *testing.B) {
  25. benchStoreSet(b, 1024, nil)
  26. }
  27. func BenchmarkStoreSet4096Bytes(b *testing.B) {
  28. benchStoreSet(b, 4096, nil)
  29. }
  30. func BenchmarkStoreSetWithJson128Bytes(b *testing.B) {
  31. benchStoreSet(b, 128, json.Marshal)
  32. }
  33. func BenchmarkStoreSetWithJson1024Bytes(b *testing.B) {
  34. benchStoreSet(b, 1024, json.Marshal)
  35. }
  36. func BenchmarkStoreSetWithJson4096Bytes(b *testing.B) {
  37. benchStoreSet(b, 4096, json.Marshal)
  38. }
  39. func BenchmarkStoreDelete(b *testing.B) {
  40. b.StopTimer()
  41. s := newStore()
  42. kvs, _ := generateNRandomKV(b.N, 128)
  43. memStats := new(runtime.MemStats)
  44. runtime.GC()
  45. runtime.ReadMemStats(memStats)
  46. for i := 0; i < b.N; i++ {
  47. _, err := s.Set(kvs[i][0], false, kvs[i][1], TTLOptionSet{ExpireTime: Permanent})
  48. if err != nil {
  49. panic(err)
  50. }
  51. }
  52. setMemStats := new(runtime.MemStats)
  53. runtime.GC()
  54. runtime.ReadMemStats(setMemStats)
  55. b.StartTimer()
  56. for i := range kvs {
  57. s.Delete(kvs[i][0], false, false)
  58. }
  59. b.StopTimer()
  60. // clean up
  61. e, err := s.Get("/", false, false)
  62. if err != nil {
  63. panic(err)
  64. }
  65. for _, n := range e.Node.Nodes {
  66. _, err := s.Delete(n.Key, true, true)
  67. if err != nil {
  68. panic(err)
  69. }
  70. }
  71. s.WatcherHub.EventHistory = nil
  72. deleteMemStats := new(runtime.MemStats)
  73. runtime.GC()
  74. runtime.ReadMemStats(deleteMemStats)
  75. fmt.Printf("\nBefore set Alloc: %v; After set Alloc: %v, After delete Alloc: %v\n",
  76. memStats.Alloc/1000, setMemStats.Alloc/1000, deleteMemStats.Alloc/1000)
  77. }
  78. func BenchmarkWatch(b *testing.B) {
  79. b.StopTimer()
  80. s := newStore()
  81. kvs, _ := generateNRandomKV(b.N, 128)
  82. b.StartTimer()
  83. memStats := new(runtime.MemStats)
  84. runtime.GC()
  85. runtime.ReadMemStats(memStats)
  86. for i := 0; i < b.N; i++ {
  87. w, _ := s.Watch(kvs[i][0], false, false, 0)
  88. e := newEvent("set", kvs[i][0], uint64(i+1), uint64(i+1))
  89. s.WatcherHub.notify(e)
  90. <-w.EventChan()
  91. s.CurrentIndex++
  92. }
  93. s.WatcherHub.EventHistory = nil
  94. afterMemStats := new(runtime.MemStats)
  95. runtime.GC()
  96. runtime.ReadMemStats(afterMemStats)
  97. fmt.Printf("\nBefore Alloc: %v; After Alloc: %v\n",
  98. memStats.Alloc/1000, afterMemStats.Alloc/1000)
  99. }
  100. func BenchmarkWatchWithSet(b *testing.B) {
  101. b.StopTimer()
  102. s := newStore()
  103. kvs, _ := generateNRandomKV(b.N, 128)
  104. b.StartTimer()
  105. for i := 0; i < b.N; i++ {
  106. w, _ := s.Watch(kvs[i][0], false, false, 0)
  107. s.Set(kvs[i][0], false, "test", TTLOptionSet{ExpireTime: Permanent})
  108. <-w.EventChan()
  109. }
  110. }
  111. func BenchmarkWatchWithSetBatch(b *testing.B) {
  112. b.StopTimer()
  113. s := newStore()
  114. kvs, _ := generateNRandomKV(b.N, 128)
  115. b.StartTimer()
  116. watchers := make([]Watcher, b.N)
  117. for i := 0; i < b.N; i++ {
  118. watchers[i], _ = s.Watch(kvs[i][0], false, false, 0)
  119. }
  120. for i := 0; i < b.N; i++ {
  121. s.Set(kvs[i][0], false, "test", TTLOptionSet{ExpireTime: Permanent})
  122. }
  123. for i := 0; i < b.N; i++ {
  124. <-watchers[i].EventChan()
  125. }
  126. }
  127. func BenchmarkWatchOneKey(b *testing.B) {
  128. s := newStore()
  129. watchers := make([]Watcher, b.N)
  130. for i := 0; i < b.N; i++ {
  131. watchers[i], _ = s.Watch("/foo", false, false, 0)
  132. }
  133. s.Set("/foo", false, "", TTLOptionSet{ExpireTime: Permanent})
  134. for i := 0; i < b.N; i++ {
  135. <-watchers[i].EventChan()
  136. }
  137. }
  138. func benchStoreSet(b *testing.B, valueSize int, process func(interface{}) ([]byte, error)) {
  139. s := newStore()
  140. b.StopTimer()
  141. kvs, size := generateNRandomKV(b.N, valueSize)
  142. b.StartTimer()
  143. for i := 0; i < b.N; i++ {
  144. resp, err := s.Set(kvs[i][0], false, kvs[i][1], TTLOptionSet{ExpireTime: Permanent})
  145. if err != nil {
  146. panic(err)
  147. }
  148. if process != nil {
  149. _, err = process(resp)
  150. if err != nil {
  151. panic(err)
  152. }
  153. }
  154. }
  155. kvs = nil
  156. b.StopTimer()
  157. memStats := new(runtime.MemStats)
  158. runtime.GC()
  159. runtime.ReadMemStats(memStats)
  160. fmt.Printf("\nAlloc: %vKB; Data: %vKB; Kvs: %v; Alloc/Data:%v\n",
  161. memStats.Alloc/1000, size/1000, b.N, memStats.Alloc/size)
  162. }
  163. func generateNRandomKV(n int, valueSize int) ([][]string, uint64) {
  164. var size uint64
  165. kvs := make([][]string, n)
  166. bytes := make([]byte, valueSize)
  167. for i := 0; i < n; i++ {
  168. kvs[i] = make([]string, 2)
  169. kvs[i][0] = fmt.Sprintf("/%010d/%010d/%010d", n, n, n)
  170. kvs[i][1] = string(bytes)
  171. size = size + uint64(len(kvs[i][0])) + uint64(len(kvs[i][1]))
  172. }
  173. return kvs, size
  174. }