tile38/vendor/github.com/cespare/xxhash/xxhashbench/xxhashbench_test.go

161 lines
3.5 KiB
Go

package xxhashbench
import (
"fmt"
"hash/crc32"
"hash/fnv"
"testing"
OneOfOne "github.com/OneOfOne/xxhash"
"github.com/cespare/xxhash/v2"
"github.com/spaolacci/murmur3"
)
var sink uint64
var benchmarks = []struct {
name string
directBytes func([]byte) uint64
directString func(string) uint64
digestBytes func([]byte) uint64
digestString func(string) uint64
}{
{
name: "xxhash",
directBytes: xxhash.Sum64,
directString: xxhash.Sum64String,
digestBytes: func(b []byte) uint64 {
h := xxhash.New()
h.Write(b)
return h.Sum64()
},
digestString: func(s string) uint64 {
h := xxhash.New()
h.WriteString(s)
return h.Sum64()
},
},
{
name: "OneOfOne",
directBytes: OneOfOne.Checksum64,
directString: OneOfOne.ChecksumString64,
digestBytes: func(b []byte) uint64 {
h := OneOfOne.New64()
h.Write(b)
return h.Sum64()
},
digestString: func(s string) uint64 {
h := OneOfOne.New64()
h.WriteString(s)
return h.Sum64()
},
},
{
name: "murmur3",
directBytes: murmur3.Sum64,
directString: func(s string) uint64 {
return murmur3.Sum64([]byte(s))
},
digestBytes: func(b []byte) uint64 {
h := murmur3.New64()
h.Write(b)
return h.Sum64()
},
digestString: func(s string) uint64 {
h := murmur3.New64()
h.Write([]byte(s))
return h.Sum64()
},
},
{
name: "CRC-32",
directBytes: func(b []byte) uint64 {
return uint64(crc32.ChecksumIEEE(b))
},
directString: func(s string) uint64 {
return uint64(crc32.ChecksumIEEE([]byte(s)))
},
digestBytes: func(b []byte) uint64 {
h := crc32.NewIEEE()
h.Write(b)
return uint64(h.Sum32())
},
digestString: func(s string) uint64 {
h := crc32.NewIEEE()
h.Write([]byte(s))
return uint64(h.Sum32())
},
},
{
name: "FNV-1a",
digestBytes: func(b []byte) uint64 {
h := fnv.New64()
h.Write(b)
return h.Sum64()
},
digestString: func(s string) uint64 {
h := fnv.New64a()
h.Write([]byte(s))
return h.Sum64()
},
},
}
func BenchmarkHashes(b *testing.B) {
for _, bb := range benchmarks {
for _, benchSize := range []struct {
name string
n int
}{
{"5B", 5},
{"100B", 100},
{"4KB", 4e3},
{"10MB", 10e6},
} {
input := make([]byte, benchSize.n)
for i := range input {
input[i] = byte(i)
}
inputString := string(input)
if bb.directBytes != nil {
name := fmt.Sprintf("%s,direct,bytes,n=%s", bb.name, benchSize.name)
b.Run(name, func(b *testing.B) {
benchmarkHashBytes(b, input, bb.directBytes)
})
}
if bb.directString != nil {
name := fmt.Sprintf("%s,direct,string,n=%s", bb.name, benchSize.name)
b.Run(name, func(b *testing.B) {
benchmarkHashString(b, inputString, bb.directString)
})
}
if bb.digestBytes != nil {
name := fmt.Sprintf("%s,digest,bytes,n=%s", bb.name, benchSize.name)
b.Run(name, func(b *testing.B) {
benchmarkHashBytes(b, input, bb.digestBytes)
})
}
if bb.digestString != nil {
name := fmt.Sprintf("%s,digest,string,n=%s", bb.name, benchSize.name)
b.Run(name, func(b *testing.B) {
benchmarkHashString(b, inputString, bb.digestString)
})
}
}
}
}
func benchmarkHashBytes(b *testing.B, input []byte, fn func([]byte) uint64) {
b.SetBytes(int64(len(input)))
for i := 0; i < b.N; i++ {
sink = fn(input)
}
}
func benchmarkHashString(b *testing.B, input string, fn func(string) uint64) {
b.SetBytes(int64(len(input)))
for i := 0; i < b.N; i++ {
sink = fn(input)
}
}