github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/triedb/pathdb/difflayer_test.go (about)

     1  // Copyright 2019 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package pathdb
    18  
    19  import (
    20  	"bytes"
    21  	"testing"
    22  
    23  	"github.com/ethereum/go-ethereum/common"
    24  	"github.com/ethereum/go-ethereum/core/rawdb"
    25  	"github.com/ethereum/go-ethereum/crypto"
    26  	"github.com/ethereum/go-ethereum/internal/testrand"
    27  	"github.com/ethereum/go-ethereum/trie/trienode"
    28  )
    29  
    30  func emptyLayer() *diskLayer {
    31  	return &diskLayer{
    32  		db:     New(rawdb.NewMemoryDatabase(), nil, false),
    33  		buffer: newNodeBuffer(DefaultBufferSize, nil, 0),
    34  	}
    35  }
    36  
    37  // goos: darwin
    38  // goarch: arm64
    39  // pkg: github.com/ethereum/go-ethereum/trie
    40  // BenchmarkSearch128Layers
    41  // BenchmarkSearch128Layers-8   	  243826	      4755 ns/op
    42  func BenchmarkSearch128Layers(b *testing.B) { benchmarkSearch(b, 0, 128) }
    43  
    44  // goos: darwin
    45  // goarch: arm64
    46  // pkg: github.com/ethereum/go-ethereum/trie
    47  // BenchmarkSearch512Layers
    48  // BenchmarkSearch512Layers-8   	   49686	     24256 ns/op
    49  func BenchmarkSearch512Layers(b *testing.B) { benchmarkSearch(b, 0, 512) }
    50  
    51  // goos: darwin
    52  // goarch: arm64
    53  // pkg: github.com/ethereum/go-ethereum/trie
    54  // BenchmarkSearch1Layer
    55  // BenchmarkSearch1Layer-8   	14062725	        88.40 ns/op
    56  func BenchmarkSearch1Layer(b *testing.B) { benchmarkSearch(b, 127, 128) }
    57  
    58  func benchmarkSearch(b *testing.B, depth int, total int) {
    59  	var (
    60  		npath []byte
    61  		nblob []byte
    62  	)
    63  	// First, we set up 128 diff layers, with 3K items each
    64  	fill := func(parent layer, index int) *diffLayer {
    65  		nodes := make(map[common.Hash]map[string]*trienode.Node)
    66  		nodes[common.Hash{}] = make(map[string]*trienode.Node)
    67  		for i := 0; i < 3000; i++ {
    68  			var (
    69  				path = testrand.Bytes(32)
    70  				blob = testrand.Bytes(100)
    71  				node = trienode.New(crypto.Keccak256Hash(blob), blob)
    72  			)
    73  			nodes[common.Hash{}][string(path)] = node
    74  			if npath == nil && depth == index {
    75  				npath = common.CopyBytes(path)
    76  				nblob = common.CopyBytes(blob)
    77  			}
    78  		}
    79  		return newDiffLayer(parent, common.Hash{}, 0, 0, nodes, nil)
    80  	}
    81  	var layer layer
    82  	layer = emptyLayer()
    83  	for i := 0; i < total; i++ {
    84  		layer = fill(layer, i)
    85  	}
    86  	b.ResetTimer()
    87  
    88  	var (
    89  		have []byte
    90  		err  error
    91  	)
    92  	for i := 0; i < b.N; i++ {
    93  		have, _, _, err = layer.node(common.Hash{}, npath, 0)
    94  		if err != nil {
    95  			b.Fatal(err)
    96  		}
    97  	}
    98  	if !bytes.Equal(have, nblob) {
    99  		b.Fatalf("have %x want %x", have, nblob)
   100  	}
   101  }
   102  
   103  // goos: darwin
   104  // goarch: arm64
   105  // pkg: github.com/ethereum/go-ethereum/trie
   106  // BenchmarkPersist
   107  // BenchmarkPersist-8   	      10	 111252975 ns/op
   108  func BenchmarkPersist(b *testing.B) {
   109  	// First, we set up 128 diff layers, with 3K items each
   110  	fill := func(parent layer) *diffLayer {
   111  		nodes := make(map[common.Hash]map[string]*trienode.Node)
   112  		nodes[common.Hash{}] = make(map[string]*trienode.Node)
   113  		for i := 0; i < 3000; i++ {
   114  			var (
   115  				path = testrand.Bytes(32)
   116  				blob = testrand.Bytes(100)
   117  				node = trienode.New(crypto.Keccak256Hash(blob), blob)
   118  			)
   119  			nodes[common.Hash{}][string(path)] = node
   120  		}
   121  		return newDiffLayer(parent, common.Hash{}, 0, 0, nodes, nil)
   122  	}
   123  	for i := 0; i < b.N; i++ {
   124  		b.StopTimer()
   125  		var layer layer
   126  		layer = emptyLayer()
   127  		for i := 1; i < 128; i++ {
   128  			layer = fill(layer)
   129  		}
   130  		b.StartTimer()
   131  
   132  		dl, ok := layer.(*diffLayer)
   133  		if !ok {
   134  			break
   135  		}
   136  		dl.persist(false)
   137  	}
   138  }
   139  
   140  // BenchmarkJournal benchmarks the performance for journaling the layers.
   141  //
   142  // BenchmarkJournal
   143  // BenchmarkJournal-8   	      10	 110969279 ns/op
   144  func BenchmarkJournal(b *testing.B) {
   145  	b.SkipNow()
   146  
   147  	// First, we set up 128 diff layers, with 3K items each
   148  	fill := func(parent layer) *diffLayer {
   149  		nodes := make(map[common.Hash]map[string]*trienode.Node)
   150  		nodes[common.Hash{}] = make(map[string]*trienode.Node)
   151  		for i := 0; i < 3000; i++ {
   152  			var (
   153  				path = testrand.Bytes(32)
   154  				blob = testrand.Bytes(100)
   155  				node = trienode.New(crypto.Keccak256Hash(blob), blob)
   156  			)
   157  			nodes[common.Hash{}][string(path)] = node
   158  		}
   159  		// TODO(rjl493456442) a non-nil state set is expected.
   160  		return newDiffLayer(parent, common.Hash{}, 0, 0, nodes, nil)
   161  	}
   162  	var layer layer
   163  	layer = emptyLayer()
   164  	for i := 0; i < 128; i++ {
   165  		layer = fill(layer)
   166  	}
   167  	b.ResetTimer()
   168  
   169  	for i := 0; i < b.N; i++ {
   170  		layer.journal(new(bytes.Buffer))
   171  	}
   172  }