Skip to content

Commit cbe221c

Browse files
author
beorn7
committed
Switch to sync.Pool.
sync.Pool is after all faster than the home-made free list. Especially under contention. To prove that, this commit also adds a benchmark for concurrent fingerprint calculation. Benchmark results: (Run with -cpu=1,2,4. x-y -> x goroutines with GOMAXPROCS=y.) benchmark old ns/op new ns/op delta BenchmarkMetricToFingerprintTripleConc4-4 320 138 -56.88% BenchmarkMetricToFingerprintTripleConc8-4 314 141 -55.10% BenchmarkMetricToFingerprintTripleConc4-2 344 264 -23.26% BenchmarkMetricToFingerprintTripleConc2-4 331 256 -22.66% BenchmarkMetricToFingerprintTripleConc8-2 338 263 -22.19% BenchmarkMetricToFingerprintTripleConc1-4 599 505 -15.69% BenchmarkMetricToFingerprintTripleConc4 553 493 -10.85% BenchmarkMetricToFingerprintTripleConc2-2 327 292 -10.70% BenchmarkMetricToFingerprintTripleConc8 554 496 -10.47% BenchmarkMetricToFingerprintTripleConc2 555 501 -9.73% BenchmarkMetricToFingerprintTripleConc1 554 509 -8.12% BenchmarkMetricToFingerprintTripleConc1-2 551 513 -6.90%
1 parent 1002745 commit cbe221c

File tree

2 files changed

+44
-9
lines changed

2 files changed

+44
-9
lines changed

model/signature.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"bytes"
1818
"hash"
1919
"hash/fnv"
20+
"sync"
2021
)
2122

2223
// SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is
@@ -28,7 +29,7 @@ var (
2829
// cache the signature of an empty label set.
2930
emptyLabelSignature = fnv.New64a().Sum64()
3031

31-
hashAndBufPool = make(chan *hashAndBuf, 1024)
32+
hashAndBufPool sync.Pool
3233
)
3334

3435
type hashAndBuf struct {
@@ -37,19 +38,15 @@ type hashAndBuf struct {
3738
}
3839

3940
func getHashAndBuf() *hashAndBuf {
40-
select {
41-
case hb := <-hashAndBufPool:
42-
return hb
43-
default:
41+
hb := hashAndBufPool.Get()
42+
if hb == nil {
4443
return &hashAndBuf{h: fnv.New64a()}
4544
}
45+
return hb.(*hashAndBuf)
4646
}
4747

4848
func putHashAndBuf(hb *hashAndBuf) {
49-
select {
50-
case hashAndBufPool <- hb:
51-
default:
52-
}
49+
hashAndBufPool.Put(hb)
5350
}
5451

5552
// LabelsToSignature returns a unique signature (i.e., fingerprint) for a given

model/signature_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ package model
1515

1616
import (
1717
"runtime"
18+
"sync"
1819
"testing"
1920
)
2021

@@ -216,3 +217,40 @@ func TestEmptyLabelSignature(t *testing.T) {
216217
t.Fatal("expected LabelsToSignature with empty labels not to perform allocations")
217218
}
218219
}
220+
221+
func benchmarkMetricToFingerprintConc(b *testing.B, m Metric, e Fingerprint, concLevel int) {
222+
var start, end sync.WaitGroup
223+
start.Add(1)
224+
end.Add(concLevel)
225+
226+
for i := 0; i < concLevel; i++ {
227+
go func() {
228+
start.Wait()
229+
for j := b.N / concLevel; j >= 0; j-- {
230+
if a := metricToFingerprint(m); a != e {
231+
b.Fatalf("expected signature of %d for %s, got %d", e, m, a)
232+
}
233+
}
234+
end.Done()
235+
}()
236+
}
237+
b.ResetTimer()
238+
start.Done()
239+
end.Wait()
240+
}
241+
242+
func BenchmarkMetricToFingerprintTripleConc1(b *testing.B) {
243+
benchmarkMetricToFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 1)
244+
}
245+
246+
func BenchmarkMetricToFingerprintTripleConc2(b *testing.B) {
247+
benchmarkMetricToFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 2)
248+
}
249+
250+
func BenchmarkMetricToFingerprintTripleConc4(b *testing.B) {
251+
benchmarkMetricToFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 4)
252+
}
253+
254+
func BenchmarkMetricToFingerprintTripleConc8(b *testing.B) {
255+
benchmarkMetricToFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 8)
256+
}

0 commit comments

Comments
 (0)