// Copyright 2017 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package test import ( "crypto/rand" "fmt" "hash/crc32" "testing" "github.com/cespare/xxhash/v2" sip13 "github.com/dgryski/go-sip13" ) type pair struct { name, value string } var testInput = []pair{ {"job", "node"}, {"instance", "123.123.1.211:9090"}, {"path", "/api/v1/namespaces//deployments/"}, {"method", "GET"}, {"namespace", "system"}, {"status", "500"}, } func BenchmarkHash(b *testing.B) { input := []byte{} for _, v := range testInput { input = append(input, v.name...) input = append(input, '\xff') input = append(input, v.value...) input = append(input, '\xff') } var total uint64 var k0 uint64 = 0x0706050403020100 var k1 uint64 = 0x0f0e0d0c0b0a0908 for name, f := range map[string]func(b []byte) uint64{ "xxhash": xxhash.Sum64, "fnv64": fnv64a, "sip13": func(b []byte) uint64 { return sip13.Sum64(k0, k1, b) }, } { b.Run(name, func(b *testing.B) { b.SetBytes(int64(len(input))) total = 0 for i := 0; i < b.N; i++ { total += f(input) } }) } } // hashAdd adds a string to a fnv64a hash value, returning the updated hash. func fnv64a(b []byte) uint64 { const ( offset64 = 14695981039346656037 prime64 = 1099511628211 ) h := uint64(offset64) for x := range b { h ^= uint64(x) h *= prime64 } return h } func BenchmarkCRC32_diff(b *testing.B) { data := [][]byte{} for i := 0; i < 1000; i++ { b := make([]byte, 512) rand.Read(b) data = append(data, b) } ctab := crc32.MakeTable(crc32.Castagnoli) total := uint32(0) b.Run("direct", func(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { total += crc32.Checksum(data[i%1000], ctab) } }) b.Run("hash-reuse", func(b *testing.B) { b.ReportAllocs() h := crc32.New(ctab) for i := 0; i < b.N; i++ { h.Reset() h.Write(data[i%1000]) total += h.Sum32() } }) b.Run("hash-new", func(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { h := crc32.New(ctab) h.Write(data[i%1000]) total += h.Sum32() } }) fmt.Println(total) }