diff --git a/trie/zk_trie_database.go b/trie/zk_trie_database.go index 308fc9c72332..fd00678f1ffe 100644 --- a/trie/zk_trie_database.go +++ b/trie/zk_trie_database.go @@ -42,10 +42,24 @@ func (l *ZktrieDatabase) Get(key []byte) ([]byte, error) { if ok { return value, nil } + + if l.db.cleans != nil { + if enc := l.db.cleans.Get(nil, concatKey); enc != nil { + memcacheCleanHitMeter.Mark(1) + memcacheCleanReadMeter.Mark(int64(len(enc))) + return enc, nil + } + } + v, err := l.db.diskdb.Get(concatKey) if err == leveldb.ErrNotFound { return nil, ErrNotFound } + if l.db.cleans != nil { + l.db.cleans.Set(concatKey[:], v) + memcacheCleanMissMeter.Mark(1) + memcacheCleanWriteMeter.Mark(int64(len(v))) + } return v, err } diff --git a/trie/zk_trie_test.go b/trie/zk_trie_test.go index fc8ae34da821..dc1923e052aa 100644 --- a/trie/zk_trie_test.go +++ b/trie/zk_trie_test.go @@ -18,6 +18,9 @@ package trie import ( "bytes" + "encoding/binary" + "io/ioutil" + "os" "runtime" "sync" "testing" @@ -27,6 +30,7 @@ import ( zkt "github.com/scroll-tech/zktrie/types" "github.com/scroll-tech/go-ethereum/common" + "github.com/scroll-tech/go-ethereum/ethdb/leveldb" "github.com/scroll-tech/go-ethereum/ethdb/memorydb" ) @@ -148,3 +152,74 @@ func TestZkTrieConcurrency(t *testing.T) { // Wait for all threads to finish pend.Wait() } + +func tempDBZK(b *testing.B) (string, *Database) { + dir, err := ioutil.TempDir("", "zktrie-bench") + assert.NoError(b, err) + + diskdb, err := leveldb.New(dir, 256, 0, "", false) + assert.NoError(b, err) + config := &Config{Cache: 256, Preimages: true, Zktrie: true} + return dir, NewDatabaseWithConfig(diskdb, config) +} + +const benchElemCountZk = 10000 + +func BenchmarkZkTrieGet(b *testing.B) { + _, tmpdb := tempDBZK(b) + zkTrie, _ := NewZkTrie(common.Hash{}, NewZktrieDatabaseFromTriedb(tmpdb)) + defer func() { + ldb := zkTrie.db.db.diskdb.(*leveldb.Database) + ldb.Close() + os.RemoveAll(ldb.Path()) + }() + + k := make([]byte, 32) + for i := 0; i < benchElemCountZk; i++ { + binary.LittleEndian.PutUint64(k, uint64(i)) + + err := zkTrie.TryUpdate(k, k) + assert.NoError(b, err) + } + + zkTrie.db.db.Commit(common.Hash{}, true, nil) + b.ResetTimer() + for i := 0; i < b.N; i++ { + binary.LittleEndian.PutUint64(k, uint64(i)) + _, err := zkTrie.TryGet(k) + assert.NoError(b, err) + } + b.StopTimer() +} + +func BenchmarkZkTrieUpdate(b *testing.B) { + _, tmpdb := tempDBZK(b) + zkTrie, _ := NewZkTrie(common.Hash{}, NewZktrieDatabaseFromTriedb(tmpdb)) + defer func() { + ldb := zkTrie.db.db.diskdb.(*leveldb.Database) + ldb.Close() + os.RemoveAll(ldb.Path()) + }() + + k := make([]byte, 32) + v := make([]byte, 32) + b.ReportAllocs() + + for i := 0; i < benchElemCountZk; i++ { + binary.LittleEndian.PutUint64(k, uint64(i)) + err := zkTrie.TryUpdate(k, k) + assert.NoError(b, err) + } + binary.LittleEndian.PutUint64(k, benchElemCountZk/2) + + //zkTrie.Commit(nil) + zkTrie.db.db.Commit(common.Hash{}, true, nil) + b.ResetTimer() + for i := 0; i < b.N; i++ { + binary.LittleEndian.PutUint64(k, uint64(i)) + binary.LittleEndian.PutUint64(v, 0xffffffff+uint64(i)) + err := zkTrie.TryUpdate(k, v) + assert.NoError(b, err) + } + b.StopTimer() +}