[crypto] Optimize the FromRLP with sync pool, and provide benchmarks to approve the performance improvement
parent
c4a9b77bee
commit
a67b7b028b
@ -0,0 +1,77 @@ |
||||
package hash |
||||
|
||||
import ( |
||||
"testing" |
||||
|
||||
"github.com/ethereum/go-ethereum/common" |
||||
"github.com/ethereum/go-ethereum/rlp" |
||||
"golang.org/x/crypto/sha3" |
||||
) |
||||
|
||||
// This test file test the bench mark of running `FromRLP` with or without usage of sync.Pool
|
||||
// in single-threaded / multi-threaded case.
|
||||
//
|
||||
// Here is the test results:
|
||||
//
|
||||
// > go test -bench=. -benchmem
|
||||
// goos: darwin
|
||||
// goarch: amd64
|
||||
// pkg: github.com/harmony-one/harmony/crypto/hash
|
||||
// BenchmarkFromRLP_MultiThreaded-12 4841481 263 ns/op 560 B/op 5 allocs/op
|
||||
// BenchmarkFromRLPNoPool_MultiThreaded-12 3665227 344 ns/op 1008 B/op 6 allocs/op
|
||||
// BenchmarkFromRLP_SingleThreaded-12 1303647 909 ns/op 560 B/op 5 allocs/op
|
||||
// BenchmarkFromRLPNoPool_SingleThreaded-12 1296238 920 ns/op 1008 B/op 6 allocs/op
|
||||
// PASS
|
||||
// ok github.com/harmony-one/harmony/crypto/hash 7.441s
|
||||
//
|
||||
// We can see that FromRLP with sync pool implementation has better memory and CPU performance over
|
||||
// the implementation without sync pool. This is because the sync pool implementation will reuse
|
||||
// the hasher and results in better performance both in CPU and memory. The huge CPU difference
|
||||
// in multi-threading benchmark actually results from sync.Pool's optimization over golang's GC
|
||||
// mechanism.
|
||||
|
||||
func BenchmarkFromRLP_MultiThreaded(b *testing.B) { |
||||
b.RunParallel(func(pb *testing.PB) { |
||||
for pb.Next() { |
||||
FromRLP(testObj) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
func BenchmarkFromRLPNoPool_MultiThreaded(b *testing.B) { |
||||
b.RunParallel(func(pb *testing.PB) { |
||||
for pb.Next() { |
||||
fromRLPNoPool(testObj) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
func BenchmarkFromRLP_SingleThreaded(b *testing.B) { |
||||
for i := 0; i != b.N; i++ { |
||||
FromRLP(testObj) |
||||
} |
||||
} |
||||
|
||||
func BenchmarkFromRLPNoPool_SingleThreaded(b *testing.B) { |
||||
for i := 0; i != b.N; i++ { |
||||
fromRLPNoPool(testObj) |
||||
} |
||||
} |
||||
|
||||
// fromRLPNoPool is a compared function to showcase the FromRLP function with sync pool
|
||||
func fromRLPNoPool(x interface{}) (h common.Hash) { |
||||
hw := sha3.NewLegacyKeccak256() |
||||
rlp.Encode(hw, x) |
||||
hw.Sum(h[:0]) |
||||
return h |
||||
} |
||||
|
||||
var testObj = testStruct{ |
||||
field1: "harmony", |
||||
field2: 1024, |
||||
} |
||||
|
||||
type testStruct struct { |
||||
field1 string |
||||
field2 int |
||||
} |
Loading…
Reference in new issue