Move benchmarks to their own module This avoids all dependencies for users. It also fixes the weird v1 self-dependency. Fixes #28
diff --git a/go.mod b/go.mod index b83ab6a..e81cef1 100644 --- a/go.mod +++ b/go.mod
@@ -1,7 +1,3 @@ module github.com/cespare/xxhash/v2 -require ( - github.com/OneOfOne/xxhash v1.2.2 - github.com/cespare/xxhash v1.1.0 // indirect - github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 -) +go 1.13
diff --git a/go.sum b/go.sum index a7f1832..e69de29 100644 --- a/go.sum +++ b/go.sum
@@ -1,6 +0,0 @@ -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
diff --git a/xxhash_test.go b/xxhash_test.go index 6e7020c..414e34a 100644 --- a/xxhash_test.go +++ b/xxhash_test.go
@@ -4,13 +4,8 @@ "bytes" "encoding/binary" "fmt" - "hash/crc32" - "hash/fnv" "strings" "testing" - - OneOfOne "github.com/OneOfOne/xxhash" - "github.com/spaolacci/murmur3" ) func TestAll(t *testing.T) { @@ -134,6 +129,8 @@ } } +var sink uint64 + func TestAllocs(t *testing.T) { const shortStr = "abcdefghijklmnop" // Sum64([]byte(shortString)) shouldn't allocate because the @@ -163,151 +160,3 @@ t.Fatalf("got %d allocation(s) (want zero)", allocs) } } - -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: Sum64, - directString: Sum64String, - digestBytes: func(b []byte) uint64 { - h := New() - h.Write(b) - return h.Sum64() - }, - digestString: func(s string) uint64 { - h := 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) - } -}
diff --git a/xxhashbench/go.mod b/xxhashbench/go.mod new file mode 100644 index 0000000..f42f101 --- /dev/null +++ b/xxhashbench/go.mod
@@ -0,0 +1,11 @@ +module github.com/cespare/xxhash/xxhashbench + +go 1.13 + +require ( + github.com/OneOfOne/xxhash v1.2.5 + github.com/cespare/xxhash/v2 v2.0.0-00010101000000-000000000000 + github.com/spaolacci/murmur3 v1.1.0 +) + +replace github.com/cespare/xxhash/v2 => ../
diff --git a/xxhashbench/go.sum b/xxhashbench/go.sum new file mode 100644 index 0000000..8bf9bcd --- /dev/null +++ b/xxhashbench/go.sum
@@ -0,0 +1,6 @@ +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/OneOfOne/xxhash v1.2.5 h1:zl/OfRA6nftbBK9qTohYBJ5xvw6C/oNKizR7cZGl3cI= +github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
diff --git a/xxhashbench/xxhashbench_test.go b/xxhashbench/xxhashbench_test.go new file mode 100644 index 0000000..a73f69e --- /dev/null +++ b/xxhashbench/xxhashbench_test.go
@@ -0,0 +1,160 @@ +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) + } +}