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