github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/accounts/benchmark_cache_test.go (about) 1 package accounts 2 3 import ( 4 "fmt" 5 "io" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "strconv" 10 "strings" 11 "testing" 12 "time" 13 ) 14 15 // These are commented because they take a pretty long time and I'm not that patient. 16 // 17 //func benchmarkCacheAccounts(n int, b *testing.B) { 18 // // 20000 -> 20k 19 // staticKeyFilesResourcePath := strconv.Itoa(n) 20 // if strings.HasSuffix(staticKeyFilesResourcePath, "000") { 21 // staticKeyFilesResourcePath = strings.TrimSuffix(staticKeyFilesResourcePath, "000") 22 // staticKeyFilesResourcePath += "k" 23 // } 24 // 25 // staticKeyFilesResourcePath, _ = filepath.Abs(filepath.Join("testdata", "benchmark_keystore"+staticKeyFilesResourcePath)) 26 // 27 // start := time.Now() 28 // cache := newAddrCache(staticKeyFilesResourcePath) 29 // cache.watcher.running = true 30 // elapsed := time.Since(start) 31 // 32 // b.Logf("establishing cache for %v accs: %v", n, elapsed) 33 // 34 // b.ResetTimer() // _benchmark_ timer, not setup timer. 35 // 36 // for i := 0; i < b.N; i++ { 37 // cache.accounts() 38 // } 39 // cache.close() 40 //} 41 //func BenchmarkCacheAccounts100(b *testing.B) { benchmarkCacheAccounts(100, b) } 42 //func BenchmarkCacheAccounts500(b *testing.B) { benchmarkCacheAccounts(500, b) } 43 //func BenchmarkCacheAccounts1000(b *testing.B) { benchmarkCacheAccounts(1000, b) } 44 //func BenchmarkCacheAccounts5000(b *testing.B) { benchmarkCacheAccounts(5000, b) } 45 //func BenchmarkCacheAccounts10000(b *testing.B) { benchmarkCacheAccounts(10000, b) } 46 //func BenchmarkCacheAccounts20000(b *testing.B) { benchmarkCacheAccounts(20000, b) } 47 //func BenchmarkCacheAccounts100000(b *testing.B) { benchmarkCacheAccounts(100000, b) } 48 //func BenchmarkCacheAccounts200000(b *testing.B) { benchmarkCacheAccounts(200000, b) } 49 //func BenchmarkCacheAccounts500000(b *testing.B) { benchmarkCacheAccounts(500000, b) } 50 51 // ac.add checks ac.all to see if given account already exists in cache, 52 // iff it doesn't, it adds account to byAddr map. 53 // 54 // No accounts added here are existing in cache, so *sort.Search* will iterate through all 55 // cached accounts _up to_ relevant alphabetizing. This is somewhat redundant to test cache.accounts(), 56 // except will test sort.Search instead of sort.Sort. 57 // 58 // Note that this _does not_ include ac.newAddrCache. 59 func benchmarkCacheAdd(n int, b *testing.B) { 60 61 // 20000 -> 20k 62 staticKeyFilesResourcePath := strconv.Itoa(n) 63 if strings.HasSuffix(staticKeyFilesResourcePath, "000") { 64 staticKeyFilesResourcePath = strings.TrimSuffix(staticKeyFilesResourcePath, "000") 65 staticKeyFilesResourcePath += "k" 66 } 67 68 staticKeyFilesResourcePath, _ = filepath.Abs(filepath.Join("testdata", "benchmark_keystore"+staticKeyFilesResourcePath)) 69 70 start := time.Now() 71 cache := newAddrCache(staticKeyFilesResourcePath) 72 cache.watcher.running = true 73 elapsed := time.Since(start) 74 75 b.Logf("establishing cache for %v accs: %v", n, elapsed) 76 77 b.ResetTimer() // _benchmark_ timer, not setup timer. 78 79 for i := 0; i < b.N; i++ { 80 // cacheTestAccounts are constant established in cache_test.go 81 for _, a := range cachetestAccounts { 82 cache.add(a) 83 } 84 } 85 cache.close() 86 } 87 88 func BenchmarkCacheAdd100(b *testing.B) { benchmarkCacheAdd(100, b) } 89 func BenchmarkCacheAdd500(b *testing.B) { benchmarkCacheAdd(500, b) } 90 func BenchmarkCacheAdd1000(b *testing.B) { benchmarkCacheAdd(1000, b) } 91 func BenchmarkCacheAdd5000(b *testing.B) { benchmarkCacheAdd(5000, b) } 92 func BenchmarkCacheAdd10000(b *testing.B) { benchmarkCacheAdd(10000, b) } 93 func BenchmarkCacheAdd20000(b *testing.B) { benchmarkCacheAdd(20000, b) } 94 func BenchmarkCacheAdd100000(b *testing.B) { benchmarkCacheAdd(100000, b) } 95 func BenchmarkCacheAdd200000(b *testing.B) { benchmarkCacheAdd(200000, b) } 96 func BenchmarkCacheAdd500000(b *testing.B) { benchmarkCacheAdd(500000, b) } 97 98 // ac.find checks ac.all to see if given account already exists in cache, 99 // iff it doesn't, it adds account to byAddr map. 100 // 101 // 3/4 added here are existing in cache; .find will iterate through ac.all 102 // cached, breaking only upon a find. There is no sort. method here. 103 // 104 // Note that this _does not_ include ac.newAddrCache. 105 func benchmarkCacheFind(n int, onlyExisting bool, b *testing.B) { 106 107 // 20000 -> 20k 108 staticKeyFilesResourcePath := strconv.Itoa(n) 109 if strings.HasSuffix(staticKeyFilesResourcePath, "000") { 110 staticKeyFilesResourcePath = strings.TrimSuffix(staticKeyFilesResourcePath, "000") 111 staticKeyFilesResourcePath += "k" 112 } 113 114 staticKeyFilesResourcePath, _ = filepath.Abs(filepath.Join("testdata", "benchmark_keystore"+staticKeyFilesResourcePath)) 115 116 if _, err := os.Stat(staticKeyFilesResourcePath); err != nil { 117 b.Fatal(err) 118 } 119 120 start := time.Now() 121 cache := newAddrCache(staticKeyFilesResourcePath) 122 elapsed := time.Since(start) 123 b.Logf("establishing cache for %v accs: %v", n, elapsed) 124 125 accs := cache.accounts() 126 cache.watcher.running = true 127 if len(accs) == 0 { 128 b.Fatalf("no accounts: keystore: %v", staticKeyFilesResourcePath) 129 } 130 131 // Set up 1 DNE and 3 existing accs. 132 // Using the last accs because they should take the longest to iterate to. 133 var findAccounts []Account 134 135 if !onlyExisting { 136 findAccounts = append(cachetestAccounts[(len(cachetestAccounts)-1):], accs[(len(accs)-3):]...) 137 if len(findAccounts) != 4 { 138 b.Fatalf("wrong number find accs: got: %v, want: 4", len(findAccounts)) 139 } 140 } else { 141 findAccounts = accs[(len(accs) - 4):] 142 } 143 accs = nil // clear mem? 144 145 b.ResetTimer() // _benchmark_ timer, not setup timer. 146 147 for i := 0; i < b.N; i++ { 148 for _, a := range findAccounts { 149 cache.muLock() 150 cache.find(a) 151 cache.muUnlock() 152 } 153 } 154 cache.close() 155 } 156 157 func BenchmarkCacheFind100(b *testing.B) { benchmarkCacheFind(100, false, b) } 158 func BenchmarkCacheFind500(b *testing.B) { benchmarkCacheFind(500, false, b) } 159 func BenchmarkCacheFind1000(b *testing.B) { benchmarkCacheFind(1000, false, b) } 160 func BenchmarkCacheFind5000(b *testing.B) { benchmarkCacheFind(5000, false, b) } 161 func BenchmarkCacheFind10000(b *testing.B) { benchmarkCacheFind(10000, false, b) } 162 func BenchmarkCacheFind20000(b *testing.B) { benchmarkCacheFind(20000, false, b) } 163 func BenchmarkCacheFind100000(b *testing.B) { benchmarkCacheFind(100000, false, b) } 164 func BenchmarkCacheFind200000(b *testing.B) { benchmarkCacheFind(200000, false, b) } 165 func BenchmarkCacheFind500000(b *testing.B) { benchmarkCacheFind(500000, false, b) } 166 func BenchmarkCacheFind100OnlyExisting(b *testing.B) { benchmarkCacheFind(100, true, b) } 167 func BenchmarkCacheFind500OnlyExisting(b *testing.B) { benchmarkCacheFind(500, true, b) } 168 func BenchmarkCacheFind1000OnlyExisting(b *testing.B) { benchmarkCacheFind(1000, true, b) } 169 func BenchmarkCacheFind5000OnlyExisting(b *testing.B) { benchmarkCacheFind(5000, true, b) } 170 func BenchmarkCacheFind10000OnlyExisting(b *testing.B) { benchmarkCacheFind(10000, true, b) } 171 func BenchmarkCacheFind20000OnlyExisting(b *testing.B) { benchmarkCacheFind(20000, true, b) } 172 func BenchmarkCacheFind100000OnlyExisting(b *testing.B) { benchmarkCacheFind(100000, true, b) } 173 func BenchmarkCacheFind200000OnlyExisting(b *testing.B) { benchmarkCacheFind(200000, true, b) } 174 func BenchmarkCacheFind500000OnlyExisting(b *testing.B) { benchmarkCacheFind(500000, true, b) } 175 176 // https://gist.github.com/m4ng0squ4sh/92462b38df26839a3ca324697c8cba04 177 // CopyFile copies the contents of the file named src to the file named 178 // by dst. The file will be created if it does not already exist. If the 179 // destination file exists, all it's contents will be replaced by the contents 180 // of the source file. The file mode will be copied from the source and 181 // the copied data is synced/flushed to stable storage. 182 func CopyFile(src, dst string) (err error) { 183 in, err := os.Open(src) 184 if err != nil { 185 return 186 } 187 defer in.Close() 188 189 out, err := os.Create(dst) 190 if err != nil { 191 return 192 } 193 defer func() { 194 if e := out.Close(); e != nil { 195 err = e 196 } 197 }() 198 199 _, err = io.Copy(out, in) 200 if err != nil { 201 return 202 } 203 204 err = out.Sync() 205 if err != nil { 206 return 207 } 208 209 si, err := os.Stat(src) 210 if err != nil { 211 return 212 } 213 err = os.Chmod(dst, si.Mode()) 214 if err != nil { 215 return 216 } 217 218 return 219 } 220 221 // CopyDir recursively copies a directory tree, attempting to preserve permissions. 222 // Source directory must exist. 223 // Symlinks are ignored and skipped. 224 func CopyDir(src string, dst string) (err error) { 225 src = filepath.Clean(src) 226 dst = filepath.Clean(dst) 227 228 si, err := os.Stat(src) 229 if err != nil { 230 return err 231 } 232 if !si.IsDir() { 233 return fmt.Errorf("source is not a directory") 234 } 235 236 entries, err := ioutil.ReadDir(src) 237 if err != nil { 238 return 239 } 240 241 for _, entry := range entries { 242 srcPath := filepath.Join(src, entry.Name()) 243 dstPath := filepath.Join(dst, entry.Name()) 244 245 if entry.IsDir() { 246 err = CopyDir(srcPath, dstPath) 247 if err != nil { 248 return 249 } 250 } else { 251 // Skip symlinks. 252 if entry.Mode()&os.ModeSymlink != 0 { 253 continue 254 } 255 if skipKeyFile(entry) { 256 continue 257 } 258 259 err = CopyFile(srcPath, dstPath) 260 if err != nil { 261 return 262 } 263 } 264 } 265 266 return 267 }