Skip to content

Commit

Permalink
benchmark TagValueFromEncodedTagsFast
Browse files Browse the repository at this point in the history
  • Loading branch information
vpranckaitis committed Jan 18, 2021
1 parent d3a8c38 commit c4296b6
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 0 deletions.
74 changes: 74 additions & 0 deletions src/dbnode/storage/index/convert/decoder_fast_benchmark_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package convert

import (
"github.com/m3db/m3/src/x/checked"
"github.com/m3db/m3/src/x/pool"
"github.com/m3db/m3/src/x/serialize"
"github.com/stretchr/testify/require"
"math/rand"
"testing"
)

type encodedTagsWithTagName struct {
encodedTags, tagName []byte
}

func BenchmarkTagValueFromEncodedTagsFast(b *testing.B) {
testData, err := prepareData(b)
require.NoError(b, err)

b.ResetTimer()
for i := range testData {
_, _, err := serialize.TagValueFromEncodedTagsFast(testData[i].encodedTags,
testData[i].tagName)
require.NoError(b, err)
}
}

func BenchmarkTagValueFromEncodedTagsFast2(b *testing.B) {
testData, err := prepareData(b)
require.NoError(b, err)

b.ResetTimer()
for i := range testData {
_, _, err := serialize.TagValueFromEncodedTagsFast2(testData[i].encodedTags,
testData[i].tagName)
require.NoError(b, err)
}
}

func prepareData(b *testing.B) ([]encodedTagsWithTagName, error) {
data, err := prepareIDAndEncodedTags(b)
if err != nil {
return nil, err
}

decoderPool := serialize.NewTagDecoderPool(
serialize.NewTagDecoderOptions(serialize.TagDecoderOptionsConfig{}),
pool.NewObjectPoolOptions(),
)
decoderPool.Init()
decoder := decoderPool.Get()
defer decoder.Close()

var tagNames [][]byte
decoder.Reset(checked.NewBytes(data[0].encodedTags, nil))
for decoder.Next() {
tagNames = append(tagNames, clone(decoder.Current().Name.Bytes()))
}
tagNames = append(tagNames, []byte("not_exist"))

var (
result = make([]encodedTagsWithTagName, 0, b.N)
rnd = rand.New(rand.NewSource(42))
)

for i := 0; i < b.N; i++ {
result = append(result, encodedTagsWithTagName{
encodedTags: data[i].encodedTags,
tagName: tagNames[rnd.Intn(len(tagNames))],
})
}

return result, nil
}
50 changes: 50 additions & 0 deletions src/x/serialize/decoder_fast.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,56 @@ import (
func TagValueFromEncodedTagsFast(
encodedTags []byte,
tagName []byte,
) ([]byte, bool, error) {
total := len(encodedTags)
if total < 4 {
return nil, false, fmt.Errorf(
"encoded tags too short: size=%d, need=%d", total, 4)
}

header := byteOrder.Uint16(encodedTags[:2])
encodedTags = encodedTags[2:]
if header != headerMagicNumber {
return nil, false, errIncorrectHeader
}

length := int(byteOrder.Uint16(encodedTags[:2]))
encodedTags = encodedTags[2:]

for i := 0; i < length; i++ {
if len(encodedTags) < 2 {
return nil, false, fmt.Errorf("missing size for tag name: index=%d", i)
}
numBytesName := int(byteOrder.Uint16(encodedTags[:2]))
if numBytesName == 0 {
return nil, false, errEmptyTagNameLiteral
}
encodedTags = encodedTags[2:]

bytesName := encodedTags[:numBytesName]
encodedTags = encodedTags[numBytesName:]

if len(encodedTags) < 2 {
return nil, false, fmt.Errorf("missing size for tag value: index=%d", i)
}

numBytesValue := int(byteOrder.Uint16(encodedTags[:2]))
encodedTags = encodedTags[2:]

bytesValue := encodedTags[:numBytesValue]
encodedTags = encodedTags[numBytesValue:]

if bytes.Equal(bytesName, tagName) {
return bytesValue, true, nil
}
}

return nil, false, nil
}

func TagValueFromEncodedTagsFast2(
encodedTags []byte,
tagName []byte,
) ([]byte, bool, error) {
var (
length int
Expand Down

0 comments on commit c4296b6

Please sign in to comment.