// Copyright (C) 2016 The Syncthing Authors. // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at https://mozilla.org/MPL/2.0/. package weakhash import ( "bytes" "context" "fmt" "hash" vadler32 "hash/adler32" "io" "math/rand" "os" "testing" "github.com/chmduquesne/rollinghash/adler32" "github.com/chmduquesne/rollinghash/bozo32" "github.com/chmduquesne/rollinghash/buzhash32" "github.com/chmduquesne/rollinghash/buzhash64" ) const testFile = "../model/testdata/tmpfile" const size = 128 << 10 func BenchmarkFind1MFile(b *testing.B) { b.ReportAllocs() b.SetBytes(1 << 20) for i := 0; i < b.N; i++ { fd, err := os.Open(testFile) if err != nil { b.Fatal(err) } _, err = Find(context.Background(), fd, []uint32{0, 1, 2}, size) if err != nil { b.Fatal(err) } fd.Close() } } type RollingHash interface { hash.Hash Roll(byte) } func BenchmarkBlock(b *testing.B) { tests := []struct { name string hash hash.Hash }{ { "adler32", adler32.New(), }, { "bozo32", bozo32.New(), }, { "buzhash32", buzhash32.New(), }, { "buzhash64", buzhash64.New(), }, { "vanilla-adler32", vadler32.New(), }, } sizes := []int64{128 << 10, 16 << 20} buf := make([]byte, 16<<20) rand.Read(buf) for _, testSize := range sizes { for _, test := range tests { b.Run(test.name+"-"+fmt.Sprint(testSize), func(bb *testing.B) { bb.Run("", func(bbb *testing.B) { bbb.ResetTimer() for i := 0; i < bbb.N; i++ { lr := io.LimitReader(bytes.NewReader(buf), testSize) n, err := io.Copy(test.hash, lr) if err != nil { bbb.Error(err) } if n != testSize { bbb.Errorf("%d != %d", n, testSize) } test.hash.Sum(nil) test.hash.Reset() } bbb.SetBytes(testSize) bbb.ReportAllocs() }) }) } } } func BenchmarkRoll(b *testing.B) { tests := []struct { name string hash RollingHash }{ { "adler32", adler32.New(), }, { "bozo32", bozo32.New(), }, { "buzhash32", buzhash32.New(), }, { "buzhash64", buzhash64.New(), }, } sizes := []int64{128 << 10, 16 << 20} for _, testSize := range sizes { for _, test := range tests { b.Run(test.name+"-"+fmt.Sprint(testSize), func(bb *testing.B) { bb.Run("", func(bbb *testing.B) { data := make([]byte, testSize) if _, err := test.hash.Write(data); err != nil { bbb.Error(err) } bbb.ResetTimer() for i := 0; i < bbb.N; i++ { for j := int64(0); j <= testSize; j++ { test.hash.Roll('a') } } bbb.SetBytes(testSize) bbb.ReportAllocs() }) }) } } }