From 908bcb795047390a7ffe09695cf5ae126ba9f10c Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Wed, 27 Dec 2017 15:04:24 +0100 Subject: [PATCH 1/3] Make sure to delete old versions in benchmark --- benchmarks/bench_test.go | 61 ++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/benchmarks/bench_test.go b/benchmarks/bench_test.go index 6de1c82d3..d944f334e 100644 --- a/benchmarks/bench_test.go +++ b/benchmarks/bench_test.go @@ -18,7 +18,7 @@ func randBytes(length int) []byte { return key } -func prepareTree(db db.DB, size, keyLen, dataLen int) (*iavl.VersionedTree, [][]byte) { +func prepareTree(b *testing.B, db db.DB, size, keyLen, dataLen int) (*iavl.VersionedTree, [][]byte) { t := iavl.NewVersionedTree(db, size) keys := make([][]byte, size) @@ -27,12 +27,26 @@ func prepareTree(db db.DB, size, keyLen, dataLen int) (*iavl.VersionedTree, [][] t.Set(key, randBytes(dataLen)) keys[i] = key } - t.Hash() - t.SaveVersion() + commitTree(b, t) runtime.GC() return t, keys } +// commit tree saves a new version and deletes and old one... +func commitTree(b *testing.B, t *iavl.VersionedTree) { + t.Hash() + _, version, err := t.SaveVersion() + if err != nil { + b.Errorf("Can't save: %v", err) + } + if version > 2 { + err = t.DeleteVersion(version - 2) + if err != nil { + b.Errorf("Can't delete: %v", err) + } + } +} + func runQueries(b *testing.B, t *iavl.VersionedTree, keyLen int) { for i := 0; i < b.N; i++ { q := randBytes(keyLen) @@ -65,8 +79,7 @@ func runUpdate(b *testing.B, t *iavl.VersionedTree, dataLen, blockSize int, keys key := keys[rand.Int31n(l)] t.Set(key, randBytes(dataLen)) if i%blockSize == 0 { - t.Hash() - t.SaveVersion() + commitTree(b, t) } } return t @@ -81,8 +94,7 @@ func runDelete(b *testing.B, t *iavl.VersionedTree, blockSize int, keys [][]byte // TODO: test if removed, use more keys (from insert) t.Remove(key) if i%blockSize == 0 { - t.Hash() - t.SaveVersion() + commitTree(b, t) } } return t @@ -96,7 +108,7 @@ func runBlock(b *testing.B, t *iavl.VersionedTree, keyLen, dataLen, blockSize in lastCommit := t real := t - check := t + // check := t for i := 0; i < b.N; i++ { for j := 0; j < blockSize; j++ { @@ -110,15 +122,14 @@ func runBlock(b *testing.B, t *iavl.VersionedTree, keyLen, dataLen, blockSize in data := randBytes(dataLen) // perform query and write on check and then real - check.Get(key) - check.Set(key, data) + // check.Get(key) + // check.Set(key, data) real.Get(key) real.Set(key, data) } // at the end of a block, move it all along.... - real.Hash() - real.SaveVersion() + commitTree(b, real) lastCommit = real } @@ -214,7 +225,7 @@ func runBenchmarks(b *testing.B, benchmarks []benchmark) { defer func() { err := os.RemoveAll(dirName) if err != nil { - fmt.Printf("%+v\n", err) + b.Errorf("%+v\n", err) } }() @@ -244,7 +255,7 @@ func runSuite(b *testing.B, d db.DB, initSize, blockSize, keyLen, dataLen int) { runtime.GC() init := memUseMB() - t, keys := prepareTree(d, initSize, keyLen, dataLen) + t, keys := prepareTree(b, d, initSize, keyLen, dataLen) used := memUseMB() - init fmt.Printf("Init Tree took %0.2f MB\n", used) @@ -265,15 +276,15 @@ func runSuite(b *testing.B, d db.DB, initSize, blockSize, keyLen, dataLen int) { // both of these edit size of the tree too much // need to run with their own tree - t = nil // for gc - b.Run("insert", func(sub *testing.B) { - it, _ := prepareTree(d, initSize, keyLen, dataLen) - sub.ResetTimer() - runInsert(sub, it, keyLen, dataLen, blockSize) - }) - b.Run("delete", func(sub *testing.B) { - dt, dkeys := prepareTree(d, initSize+sub.N, keyLen, dataLen) - sub.ResetTimer() - runDelete(sub, dt, blockSize, dkeys) - }) + // t = nil // for gc + // b.Run("insert", func(sub *testing.B) { + // it, _ := prepareTree(d, initSize, keyLen, dataLen) + // sub.ResetTimer() + // runInsert(sub, it, keyLen, dataLen, blockSize) + // }) + // b.Run("delete", func(sub *testing.B) { + // dt, dkeys := prepareTree(d, initSize+sub.N, keyLen, dataLen) + // sub.ResetTimer() + // runDelete(sub, dt, blockSize, dkeys) + // }) } From 58179ca9309e872a1125ee65a3d27df9779bac9b Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 2 Jan 2018 17:55:03 +0100 Subject: [PATCH 2/3] Define 20 version history for benchmark --- benchmarks/bench_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/benchmarks/bench_test.go b/benchmarks/bench_test.go index d944f334e..aa16f367a 100644 --- a/benchmarks/bench_test.go +++ b/benchmarks/bench_test.go @@ -11,6 +11,8 @@ import ( db "github.com/tendermint/tmlibs/db" ) +const historySize = 20 + func randBytes(length int) []byte { key := make([]byte, length) // math.rand.Read always returns err=nil @@ -39,8 +41,8 @@ func commitTree(b *testing.B, t *iavl.VersionedTree) { if err != nil { b.Errorf("Can't save: %v", err) } - if version > 2 { - err = t.DeleteVersion(version - 2) + if version > historySize { + err = t.DeleteVersion(version - historySize) if err != nil { b.Errorf("Can't delete: %v", err) } From 810691809711abd05ff5fb3a7d974f7981c5ec86 Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 2 Jan 2018 18:10:20 +0100 Subject: [PATCH 3/3] Add benchmarks for hash functions --- benchmarks/hash_test.go | 47 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 benchmarks/hash_test.go diff --git a/benchmarks/hash_test.go b/benchmarks/hash_test.go new file mode 100644 index 000000000..83491a9f7 --- /dev/null +++ b/benchmarks/hash_test.go @@ -0,0 +1,47 @@ +package benchmarks + +import ( + "crypto" + "fmt" + "hash" + "testing" + + _ "crypto/sha256" + + _ "golang.org/x/crypto/ripemd160" + _ "golang.org/x/crypto/sha3" +) + +func BenchmarkHash(b *testing.B) { + hashers := []struct { + name string + size int + hasher hash.Hash + }{ + {"ripemd160", 64, crypto.RIPEMD160.New()}, + {"ripemd160", 512, crypto.RIPEMD160.New()}, + {"sha2-256", 64, crypto.SHA256.New()}, + {"sha2-256", 512, crypto.SHA256.New()}, + {"sha3-256", 64, crypto.SHA3_256.New()}, + {"sha3-256", 512, crypto.SHA3_256.New()}, + } + + for _, h := range hashers { + prefix := fmt.Sprintf("%s-%d", h.name, h.size) + b.Run(prefix, func(sub *testing.B) { + benchHasher(sub, h.hasher, h.size) + }) + } +} + +func benchHasher(b *testing.B, hasher hash.Hash, size int) { + // create all random bytes before to avoid timing this + inputs := randBytes(b.N + size + 1) + + for i := 0; i < b.N; i++ { + hasher.Reset() + // grab a slice of size bytes from random string + hasher.Write(inputs[i : i+size]) + hasher.Sum(nil) + } +}