Skip to content

Commit

Permalink
Merge pull request #298 from go-faster/perf/improve-hash
Browse files Browse the repository at this point in the history
perf(otelstorage): optimize allocations in `Hash`
  • Loading branch information
ernado authored Jan 17, 2024
2 parents bb12960 + b596b06 commit 6e2ede0
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 11 deletions.
26 changes: 16 additions & 10 deletions internal/otelstorage/hash.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package otelstorage

import (
"cmp"
"encoding/binary"
"encoding/hex"
"math"
"slices"
"strings"

"github.com/zeebo/xxh3"
"go.opentelemetry.io/collector/pdata/pcommon"
Expand All @@ -25,13 +25,6 @@ func AttrHash(m pcommon.Map) Hash {
return h.Sum128().Bytes()
}

// StrHash computes string hash.
func StrHash(s string) Hash {
h := xxh3.New()
_, _ = h.WriteString(s)
return h.Sum128().Bytes()
}

func hashValue(h *xxh3.Hasher, val pcommon.Value) {
var buf [8]byte

Expand Down Expand Up @@ -76,7 +69,12 @@ func hashMap(h *xxh3.Hasher, m pcommon.Map) {
key string
value pcommon.Value
}
pairs := make([]pair, 0, m.Len())
var pairs []pair
if l := m.Len(); l < 16 {
pairs = make([]pair, 0, 16)
} else {
pairs = make([]pair, 0, m.Len())
}
m.Range(func(k string, v pcommon.Value) bool {
pairs = append(pairs, pair{
key: k,
Expand All @@ -85,7 +83,15 @@ func hashMap(h *xxh3.Hasher, m pcommon.Map) {
return true
})
slices.SortFunc(pairs, func(a, b pair) int {
return cmp.Compare(a.key, b.key)
// [cmp.Compare] has significantly worse performance
// than [strings.Compare] due to NaN checks.
//
// Note that [strings.Compare] is not intrinsified, although
// SIMD-based implementation would not give any performance
// gains, since attribute names tend to be relatively small (<64 bytes).
//
// See https://go.dev/issue/61725.
return strings.Compare(a.key, b.key)
})

for _, pair := range pairs {
Expand Down
29 changes: 28 additions & 1 deletion internal/otelstorage/hash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,32 @@ func TestHash(t *testing.T) {
m := pcommon.NewMap()
m.PutStr("foo", "bar")
require.NotEqual(t, AttrHash(m), Hash{})
require.NotEqual(t, StrHash("foo"), Hash{})
}

func BenchmarkHash(b *testing.B) {
m := pcommon.NewMap()
m.PutStr("net.transport", "ip_tcp")
m.PutStr("net.sock.family", "inet")
m.PutStr("net.sock.host.addr", "192.168.210.83")
m.PutStr("net.host.name", "shop-backend.local")
m.PutStr("http.flavor", "1.1")
m.PutStr("http.method", "PUT")
m.PutInt("http.status_code", 204)
m.PutStr("http.url", "https://shop-backend.local:8409/article-to-cart")
m.PutStr("http.scheme", "https")
m.PutStr("http.target", "/article-to-cart")
m.PutInt("http.response_content_length", 937939)
m.PutInt("http.request_content_length", 39543)

var sink Hash
b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
sink = AttrHash(m)
}

if sink == (Hash{}) {
b.Fatal("hash is zero")
}
}

0 comments on commit 6e2ede0

Please sign in to comment.