mirror of
https://github.com/tendermint/tendermint.git
synced 2026-02-07 04:20:44 +00:00
benchmark different mutex versions
This commit is contained in:
@@ -160,7 +160,7 @@ func NopMetrics() *Metrics {
|
||||
// type that is passed in.
|
||||
// This method uses a map on the Metrics struct so that each label name only needs
|
||||
// to be produced once to prevent expensive string operations.
|
||||
func (m *Metrics) ValueToMetricLabel(i interface{}) string {
|
||||
func (m *Metrics) ValueToMetricLabelRW(i interface{}) string {
|
||||
t := reflect.TypeOf(i)
|
||||
m.mtx.RLock()
|
||||
|
||||
@@ -178,3 +178,27 @@ func (m *Metrics) ValueToMetricLabel(i interface{}) string {
|
||||
m.messageLabelNames[t] = l
|
||||
return l
|
||||
}
|
||||
|
||||
// ValueToMetricLabel is a method that is used to produce a prometheus label value of the golang
|
||||
// type that is passed in.
|
||||
// This method uses a map on the Metrics struct so that each label name only needs
|
||||
// to be produced once to prevent expensive string operations.
|
||||
func (m *Metrics) ValueToMetricLabelM(i interface{}) string {
|
||||
t := reflect.TypeOf(i)
|
||||
m.mtx.Lock()
|
||||
defer m.mtx.Unlock()
|
||||
|
||||
if s, ok := m.messageLabelNames[t]; ok {
|
||||
return s
|
||||
}
|
||||
|
||||
s := t.String()
|
||||
ss := valueToLabelRegexp.FindStringSubmatch(s)
|
||||
l := fmt.Sprintf("%s_%s", ss[1], ss[2])
|
||||
m.messageLabelNames[t] = l
|
||||
return l
|
||||
}
|
||||
|
||||
func (m *Metrics) ValueToMetricLabel(i interface{}) string {
|
||||
return m.ValueToMetricLabelRW(i)
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package p2p
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tendermint/tendermint/proto/tendermint/consensus"
|
||||
"github.com/tendermint/tendermint/proto/tendermint/p2p"
|
||||
)
|
||||
|
||||
@@ -17,3 +19,112 @@ func TestValueToMetricsLabel(t *testing.T) {
|
||||
str = m.ValueToMetricLabel(r)
|
||||
assert.Equal(t, "p2p_PexResponse", str)
|
||||
}
|
||||
|
||||
func BenchmarkValueToMetricsLabel(b *testing.B) {
|
||||
numGoRoutines := 16
|
||||
msgTypes := []interface{}{
|
||||
&p2p.PexResponse{},
|
||||
&p2p.PexRequest{},
|
||||
&p2p.PexAddress{},
|
||||
&consensus.HasVote{},
|
||||
&consensus.NewRoundStep{},
|
||||
&consensus.NewValidBlock{},
|
||||
&consensus.VoteSetBits{},
|
||||
&consensus.VoteSetMaj23{},
|
||||
&consensus.Vote{},
|
||||
&consensus.BlockPart{},
|
||||
&consensus.ProposalPOL{},
|
||||
}
|
||||
b.Run("RW Mutex Version", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
b.StopTimer()
|
||||
m := NopMetrics()
|
||||
wg := &sync.WaitGroup{}
|
||||
b.StartTimer()
|
||||
for j := 0; j < numGoRoutines; j++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for k := 0; k < 100; k++ {
|
||||
m.ValueToMetricLabelRW(msgTypes[k%len(msgTypes)])
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
})
|
||||
b.Run("Mutex Version", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
b.StopTimer()
|
||||
m := NopMetrics()
|
||||
wg := &sync.WaitGroup{}
|
||||
b.StartTimer()
|
||||
for j := 0; j < numGoRoutines; j++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for k := 0; k < 100; k++ {
|
||||
m.ValueToMetricLabelM(msgTypes[k%len(msgTypes)])
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkValueToMetricsLabelPrefilled(b *testing.B) {
|
||||
numGoRoutines := 16
|
||||
msgTypes := []interface{}{
|
||||
&p2p.PexResponse{},
|
||||
&p2p.PexRequest{},
|
||||
&p2p.PexAddress{},
|
||||
&consensus.HasVote{},
|
||||
&consensus.NewRoundStep{},
|
||||
&consensus.NewValidBlock{},
|
||||
&consensus.VoteSetBits{},
|
||||
&consensus.VoteSetMaj23{},
|
||||
&consensus.Vote{},
|
||||
&consensus.BlockPart{},
|
||||
&consensus.ProposalPOL{},
|
||||
}
|
||||
// create a metric set and put all of the types into the label map.
|
||||
m := NopMetrics()
|
||||
for _, t := range msgTypes {
|
||||
m.ValueToMetricLabel(t)
|
||||
}
|
||||
b.Run("RW Mutex Version", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
b.StopTimer()
|
||||
wg := &sync.WaitGroup{}
|
||||
b.StartTimer()
|
||||
for j := 0; j < numGoRoutines; j++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for k := 0; k < 100; k++ {
|
||||
m.ValueToMetricLabelRW(msgTypes[k%len(msgTypes)])
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
})
|
||||
b.Run("Mutex Version", func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
b.StopTimer()
|
||||
wg := &sync.WaitGroup{}
|
||||
b.StartTimer()
|
||||
for j := 0; j < numGoRoutines; j++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for k := 0; k < 100; k++ {
|
||||
m.ValueToMetricLabelM(msgTypes[k%len(msgTypes)])
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user