Merge pull request #89 from prometheus/beorn7/performance

Switch to sync.Pool.
This commit is contained in:
Björn Rabenstein 2015-03-04 13:34:34 +01:00
commit b6416bc5c2
3 changed files with 45 additions and 10 deletions

View File

@ -20,7 +20,7 @@ MAC_OS_X_VERSION ?= 10.8
BUILD_PATH = $(PWD)/.build BUILD_PATH = $(PWD)/.build
export GO_VERSION = 1.4 export GO_VERSION = 1.4.2
export GOOS = $(subst Darwin,darwin,$(subst Linux,linux,$(subst FreeBSD,freebsd,$(OS)))) export GOOS = $(subst Darwin,darwin,$(subst Linux,linux,$(subst FreeBSD,freebsd,$(OS))))
ifeq ($(GOOS),darwin) ifeq ($(GOOS),darwin)

View File

@ -17,6 +17,7 @@ import (
"bytes" "bytes"
"hash" "hash"
"hash/fnv" "hash/fnv"
"sync"
) )
// SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is // SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is
@ -28,7 +29,7 @@ var (
// cache the signature of an empty label set. // cache the signature of an empty label set.
emptyLabelSignature = fnv.New64a().Sum64() emptyLabelSignature = fnv.New64a().Sum64()
hashAndBufPool = make(chan *hashAndBuf, 1024) hashAndBufPool sync.Pool
) )
type hashAndBuf struct { type hashAndBuf struct {
@ -37,19 +38,15 @@ type hashAndBuf struct {
} }
func getHashAndBuf() *hashAndBuf { func getHashAndBuf() *hashAndBuf {
select { hb := hashAndBufPool.Get()
case hb := <-hashAndBufPool: if hb == nil {
return hb
default:
return &hashAndBuf{h: fnv.New64a()} return &hashAndBuf{h: fnv.New64a()}
} }
return hb.(*hashAndBuf)
} }
func putHashAndBuf(hb *hashAndBuf) { func putHashAndBuf(hb *hashAndBuf) {
select { hashAndBufPool.Put(hb)
case hashAndBufPool <- hb:
default:
}
} }
// LabelsToSignature returns a unique signature (i.e., fingerprint) for a given // LabelsToSignature returns a unique signature (i.e., fingerprint) for a given

View File

@ -15,6 +15,7 @@ package model
import ( import (
"runtime" "runtime"
"sync"
"testing" "testing"
) )
@ -216,3 +217,40 @@ func TestEmptyLabelSignature(t *testing.T) {
t.Fatal("expected LabelsToSignature with empty labels not to perform allocations") t.Fatal("expected LabelsToSignature with empty labels not to perform allocations")
} }
} }
func benchmarkMetricToFingerprintConc(b *testing.B, m Metric, e Fingerprint, concLevel int) {
var start, end sync.WaitGroup
start.Add(1)
end.Add(concLevel)
for i := 0; i < concLevel; i++ {
go func() {
start.Wait()
for j := b.N / concLevel; j >= 0; j-- {
if a := metricToFingerprint(m); a != e {
b.Fatalf("expected signature of %d for %s, got %d", e, m, a)
}
}
end.Done()
}()
}
b.ResetTimer()
start.Done()
end.Wait()
}
func BenchmarkMetricToFingerprintTripleConc1(b *testing.B) {
benchmarkMetricToFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 1)
}
func BenchmarkMetricToFingerprintTripleConc2(b *testing.B) {
benchmarkMetricToFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 2)
}
func BenchmarkMetricToFingerprintTripleConc4(b *testing.B) {
benchmarkMetricToFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 4)
}
func BenchmarkMetricToFingerprintTripleConc8(b *testing.B) {
benchmarkMetricToFingerprintConc(b, Metric{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676, 8)
}