amortize hasher initialization for Sum256/Sum512

As expected, the performance increase is only noticeable for
small inputs:

name            old time/op    new time/op    delta
Sum256/64-4        343ns ± 4%     243ns ± 6%  -28.96%  (p=0.008 n=5+5)
Sum256/1024-4     2.62µs ± 1%    2.50µs ± 2%   -4.57%  (p=0.008 n=5+5)
Sum256/65536-4     175µs ± 1%     170µs ± 4%     ~     (p=0.190 n=4+5)

Co-authored-by: Dmitry Yu Okunev <xaionaro@dx.center>
This commit is contained in:
lukechampine 2020-02-02 14:46:41 -05:00
parent b60a0c0b5a
commit 617550f073
2 changed files with 27 additions and 7 deletions

View File

@ -406,9 +406,13 @@ func New(size int, key []byte) *Hasher {
return newHasher(keyWords, flagKeyedHash, size)
}
// Sum256 and Sum512 always use the same hasher state, so we can save some time
// when hashing small inputs by constructing the hasher ahead of time.
var defaultHasher = newHasher(iv, 0, 0)
// Sum256 returns the unkeyed BLAKE3 hash of b, truncated to 256 bits.
func Sum256(b []byte) (out [32]byte) {
h := newHasher(iv, 0, 0)
h := *defaultHasher
h.Write(b)
h.XOF().Read(out[:])
return
@ -416,7 +420,7 @@ func Sum256(b []byte) (out [32]byte) {
// Sum512 returns the unkeyed BLAKE3 hash of b, truncated to 512 bits.
func Sum512(b []byte) (out [64]byte) {
h := newHasher(iv, 0, 0)
h := *defaultHasher
h.Write(b)
h.XOF().Read(out[:])
return

View File

@ -195,11 +195,27 @@ func BenchmarkWrite(b *testing.B) {
}
func BenchmarkSum256(b *testing.B) {
b.ReportAllocs()
buf := make([]byte, 1024)
for i := 0; i < b.N; i++ {
blake3.Sum256(buf)
}
b.Run("64", func(b *testing.B) {
b.ReportAllocs()
buf := make([]byte, 64)
for i := 0; i < b.N; i++ {
blake3.Sum256(buf)
}
})
b.Run("1024", func(b *testing.B) {
b.ReportAllocs()
buf := make([]byte, 1024)
for i := 0; i < b.N; i++ {
blake3.Sum256(buf)
}
})
b.Run("65536", func(b *testing.B) {
b.ReportAllocs()
buf := make([]byte, 65536)
for i := 0; i < b.N; i++ {
blake3.Sum256(buf)
}
})
}
func BenchmarkXOF(b *testing.B) {