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  }