github.com/onflow/atree@v0.6.0/basicarray_benchmark_test.go (about) 1 /* 2 * Atree - Scalable Arrays and Ordered Maps 3 * 4 * Copyright 2021 Dapper Labs, Inc. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package atree 20 21 import ( 22 "testing" 23 "time" 24 25 "github.com/stretchr/testify/require" 26 ) 27 28 // GENERAL COMMENT: 29 // running this test with 30 // 31 // go test -bench=. -benchmem 32 // 33 // will track the heap allocations for the Benchmarks 34 func BenchmarkXSBasicArray(b *testing.B) { benchmarkBasicArray(b, 10, 100) } 35 36 func BenchmarkSBasicArray(b *testing.B) { benchmarkBasicArray(b, 1000, 100) } 37 38 func BenchmarkMBasicArray(b *testing.B) { benchmarkBasicArray(b, 10_000, 100) } 39 40 func BenchmarkLBasicArray(b *testing.B) { benchmarkBasicArray(b, 100_000, 100) } 41 42 func BenchmarkXLBasicArray(b *testing.B) { benchmarkBasicArray(b, 1_000_000, 100) } 43 44 func BenchmarkXXLBasicArray(b *testing.B) { 45 if testing.Short() { 46 b.Skip("Skipping BenchmarkXXLArray in short mode") 47 } 48 benchmarkBasicArray(b, 10_000_000, 100) 49 } 50 51 func BenchmarkXXXLBasicArray(b *testing.B) { 52 if testing.Short() { 53 b.Skip("Skipping BenchmarkXXXLArray in short mode") 54 } 55 benchmarkBasicArray(b, 100_000_000, 100) 56 } 57 58 // BenchmarkBasicArray benchmarks the performance of basic array 59 func benchmarkBasicArray(b *testing.B, initialArraySize, numberOfElements int) { 60 61 r := newRand(b) 62 63 storage := newTestPersistentStorage(b) 64 65 address := Address{1, 2, 3, 4, 5, 6, 7, 8} 66 67 array, err := NewBasicArray(storage, address) 68 require.NoError(b, err) 69 70 // TODO capture arrayID here ? 71 72 var start time.Time 73 var totalRawDataSize uint32 74 var totalAppendTime time.Duration 75 var totalRemoveTime time.Duration 76 var totalInsertTime time.Duration 77 var totalLookupTime time.Duration 78 79 // setup 80 for i := 0; i < initialArraySize; i++ { 81 v := RandomValue(r) 82 storable, err := v.Storable(storage, array.Address(), MaxInlineArrayElementSize) 83 require.NoError(b, err) 84 totalRawDataSize += storable.ByteSize() 85 err = array.Append(v) 86 require.NoError(b, err) 87 } 88 require.NoError(b, storage.Commit()) 89 b.ResetTimer() 90 91 arrayID := array.StorageID() 92 93 // append 94 storage.DropCache() 95 array, err = NewBasicArrayWithRootID(storage, arrayID) 96 require.NoError(b, err) 97 98 start = time.Now() 99 for i := 0; i < numberOfElements; i++ { 100 v := RandomValue(r) 101 storable, err := v.Storable(storage, array.Address(), MaxInlineArrayElementSize) 102 require.NoError(b, err) 103 totalRawDataSize += storable.ByteSize() 104 err = array.Append(v) 105 require.NoError(b, err) 106 } 107 require.NoError(b, storage.Commit()) 108 totalAppendTime = time.Since(start) 109 110 // remove 111 storage.DropCache() 112 array, err = NewBasicArrayWithRootID(storage, arrayID) 113 require.NoError(b, err) 114 115 start = time.Now() 116 for i := 0; i < numberOfElements; i++ { 117 ind := r.Intn(int(array.Count())) 118 s, err := array.Remove(uint64(ind)) 119 require.NoError(b, err) 120 storable, err := s.Storable(storage, array.Address(), MaxInlineArrayElementSize) 121 require.NoError(b, err) 122 totalRawDataSize -= storable.ByteSize() 123 } 124 require.NoError(b, storage.Commit()) 125 totalRemoveTime = time.Since(start) 126 127 // insert 128 storage.DropCache() 129 array, err = NewBasicArrayWithRootID(storage, arrayID) 130 require.NoError(b, err) 131 132 start = time.Now() 133 for i := 0; i < numberOfElements; i++ { 134 ind := r.Intn(int(array.Count())) 135 v := RandomValue(r) 136 storable, err := v.Storable(storage, array.Address(), MaxInlineArrayElementSize) 137 require.NoError(b, err) 138 totalRawDataSize += storable.ByteSize() 139 err = array.Insert(uint64(ind), v) 140 require.NoError(b, err) 141 } 142 require.NoError(b, storage.Commit()) 143 totalInsertTime = time.Since(start) 144 145 // lookup 146 storage.DropCache() 147 array, err = NewBasicArrayWithRootID(storage, arrayID) 148 require.NoError(b, err) 149 150 start = time.Now() 151 for i := 0; i < numberOfElements; i++ { 152 ind := r.Intn(int(array.Count())) 153 _, err := array.Get(uint64(ind)) 154 require.NoError(b, err) 155 } 156 require.NoError(b, storage.Commit()) 157 totalLookupTime = time.Since(start) 158 159 // random lookup 160 storage.baseStorage.ResetReporter() 161 storage.DropCache() 162 array, err = NewBasicArrayWithRootID(storage, arrayID) 163 require.NoError(b, err) 164 165 ind := r.Intn(int(array.Count())) 166 _, err = array.Get(uint64(ind)) 167 require.NoError(b, err) 168 storageOverheadRatio := float64(storage.baseStorage.Size()) / float64(totalRawDataSize) 169 b.ReportMetric(float64(storage.baseStorage.SegmentsTouched()), "segments_touched") 170 b.ReportMetric(float64(storage.baseStorage.SegmentCounts()), "segments_total") 171 b.ReportMetric(float64(totalRawDataSize), "storage_raw_data_size") 172 b.ReportMetric(float64(storage.baseStorage.Size()), "storage_stored_data_size") 173 b.ReportMetric(float64(storage.baseStorage.BytesRetrieved()), "storage_bytes_loaded_for_lookup") 174 b.ReportMetric(storageOverheadRatio, "storage_overhead_ratio") 175 b.ReportMetric(float64(array.Count()), "number_of_elements") 176 b.ReportMetric(float64(int(totalAppendTime)), "append_100_time_(ns)") 177 b.ReportMetric(float64(int(totalRemoveTime)), "remove_100_time_(ns)") 178 b.ReportMetric(float64(int(totalInsertTime)), "insert_100_time_(ns)") 179 b.ReportMetric(float64(int(totalLookupTime)), "lookup_100_time_(ns)") 180 // b.ReportMetric(float64(storage.BytesRetrieved()), "bytes_retrieved") 181 // b.ReportMetric(float64(storage.BytesStored()), "bytes_stored") 182 // b.ReportMetric(float64(storage.SegmentTouched()), "segments_touched" 183 }