go.etcd.io/etcd@v3.3.27+incompatible/mvcc/kvstore_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 mvcc 16 17 import ( 18 "sync/atomic" 19 "testing" 20 21 "github.com/coreos/etcd/lease" 22 "github.com/coreos/etcd/mvcc/backend" 23 ) 24 25 type fakeConsistentIndex uint64 26 27 func (i *fakeConsistentIndex) ConsistentIndex() uint64 { 28 return atomic.LoadUint64((*uint64)(i)) 29 } 30 31 func BenchmarkStorePut(b *testing.B) { 32 var i fakeConsistentIndex 33 be, tmpPath := backend.NewDefaultTmpBackend() 34 s := NewStore(be, &lease.FakeLessor{}, &i) 35 defer cleanup(s, be, tmpPath) 36 37 // arbitrary number of bytes 38 bytesN := 64 39 keys := createBytesSlice(bytesN, b.N) 40 vals := createBytesSlice(bytesN, b.N) 41 42 b.ResetTimer() 43 for i := 0; i < b.N; i++ { 44 s.Put(keys[i], vals[i], lease.NoLease) 45 } 46 } 47 48 func BenchmarkStoreRangeKey1(b *testing.B) { benchmarkStoreRange(b, 1) } 49 func BenchmarkStoreRangeKey100(b *testing.B) { benchmarkStoreRange(b, 100) } 50 51 func benchmarkStoreRange(b *testing.B, n int) { 52 var i fakeConsistentIndex 53 be, tmpPath := backend.NewDefaultTmpBackend() 54 s := NewStore(be, &lease.FakeLessor{}, &i) 55 defer cleanup(s, be, tmpPath) 56 57 // 64 byte key/val 58 keys, val := createBytesSlice(64, n), createBytesSlice(64, 1) 59 for i := range keys { 60 s.Put(keys[i], val[0], lease.NoLease) 61 } 62 // Force into boltdb tx instead of backend read tx. 63 s.Commit() 64 65 var begin, end []byte 66 if n == 1 { 67 begin, end = keys[0], nil 68 } else { 69 begin, end = []byte{}, []byte{} 70 } 71 72 b.ReportAllocs() 73 b.ResetTimer() 74 for i := 0; i < b.N; i++ { 75 s.Range(begin, end, RangeOptions{}) 76 } 77 } 78 79 func BenchmarkConsistentIndex(b *testing.B) { 80 fci := fakeConsistentIndex(10) 81 be, tmpPath := backend.NewDefaultTmpBackend() 82 s := NewStore(be, &lease.FakeLessor{}, &fci) 83 defer cleanup(s, be, tmpPath) 84 85 tx := s.b.BatchTx() 86 tx.Lock() 87 s.saveIndex(tx) 88 tx.Unlock() 89 90 b.ReportAllocs() 91 b.ResetTimer() 92 for i := 0; i < b.N; i++ { 93 s.ConsistentIndex() 94 } 95 } 96 97 // BenchmarkStoreTxnPutUpdate is same as above, but instead updates single key 98 func BenchmarkStorePutUpdate(b *testing.B) { 99 var i fakeConsistentIndex 100 be, tmpPath := backend.NewDefaultTmpBackend() 101 s := NewStore(be, &lease.FakeLessor{}, &i) 102 defer cleanup(s, be, tmpPath) 103 104 // arbitrary number of bytes 105 keys := createBytesSlice(64, 1) 106 vals := createBytesSlice(1024, 1) 107 108 b.ResetTimer() 109 for i := 0; i < b.N; i++ { 110 s.Put(keys[0], vals[0], lease.NoLease) 111 } 112 } 113 114 // BenchmarkStoreTxnPut benchmarks the Put operation 115 // with transaction begin and end, where transaction involves 116 // some synchronization operations, such as mutex locking. 117 func BenchmarkStoreTxnPut(b *testing.B) { 118 var i fakeConsistentIndex 119 be, tmpPath := backend.NewDefaultTmpBackend() 120 s := NewStore(be, &lease.FakeLessor{}, &i) 121 defer cleanup(s, be, tmpPath) 122 123 // arbitrary number of bytes 124 bytesN := 64 125 keys := createBytesSlice(bytesN, b.N) 126 vals := createBytesSlice(bytesN, b.N) 127 128 b.ResetTimer() 129 b.ReportAllocs() 130 for i := 0; i < b.N; i++ { 131 txn := s.Write() 132 txn.Put(keys[i], vals[i], lease.NoLease) 133 txn.End() 134 } 135 } 136 137 // benchmarkStoreRestore benchmarks the restore operation 138 func benchmarkStoreRestore(revsPerKey int, b *testing.B) { 139 var i fakeConsistentIndex 140 be, tmpPath := backend.NewDefaultTmpBackend() 141 s := NewStore(be, &lease.FakeLessor{}, &i) 142 // use closure to capture 's' to pick up the reassignment 143 defer func() { cleanup(s, be, tmpPath) }() 144 145 // arbitrary number of bytes 146 bytesN := 64 147 keys := createBytesSlice(bytesN, b.N) 148 vals := createBytesSlice(bytesN, b.N) 149 150 for i := 0; i < b.N; i++ { 151 for j := 0; j < revsPerKey; j++ { 152 txn := s.Write() 153 txn.Put(keys[i], vals[i], lease.NoLease) 154 txn.End() 155 } 156 } 157 s.Close() 158 159 b.ReportAllocs() 160 b.ResetTimer() 161 s = NewStore(be, &lease.FakeLessor{}, &i) 162 } 163 164 func BenchmarkStoreRestoreRevs1(b *testing.B) { 165 benchmarkStoreRestore(1, b) 166 } 167 168 func BenchmarkStoreRestoreRevs10(b *testing.B) { 169 benchmarkStoreRestore(10, b) 170 } 171 172 func BenchmarkStoreRestoreRevs20(b *testing.B) { 173 benchmarkStoreRestore(20, b) 174 }