diff --git a/trie/trie_test.go b/trie/trie_test.go index e53ac568e9..5286c490ca 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -512,6 +512,42 @@ func BenchmarkHash(b *testing.B) { trie.Hash() } +// Benchmarks the trie Commit following a Hash. Since the trie caches the result of any operation, +// we cannot use b.N as the number of hashing rouns, since all rounds apart from +// the first one will be NOOP. As such, we'll use b.N as the number of account to +// insert into the trie before measuring the hashing. +func BenchmarkCommitAfterHash(b *testing.B) { + // Make the random benchmark deterministic + random := rand.New(rand.NewSource(0)) + + // Create a realistic account trie to hash + addresses := make([][20]byte, b.N) + for i := 0; i < len(addresses); i++ { + for j := 0; j < len(addresses[i]); j++ { + addresses[i][j] = byte(random.Intn(256)) + } + } + accounts := make([][]byte, len(addresses)) + for i := 0; i < len(accounts); i++ { + var ( + nonce = uint64(random.Int63()) + balance = new(big.Int).Rand(random, new(big.Int).Exp(common.Big2, common.Big256, nil)) + root = emptyRoot + code = crypto.Keccak256(nil) + ) + accounts[i], _ = rlp.EncodeToBytes([]interface{}{nonce, balance, root, code}) + } + // Insert the accounts into the trie and hash it + trie := newEmpty() + for i := 0; i < len(addresses); i++ { + trie.Update(crypto.Keccak256(addresses[i][:]), accounts[i]) + } + trie.Hash() + b.ResetTimer() + b.ReportAllocs() + trie.Commit(nil) +} + func tempDB() (string, *Database) { dir, err := ioutil.TempDir("", "trie-bench") if err != nil {