perf: x/tx/signing/textual: remove unnecessary,expensive regex from method (#15808)

Co-authored-by: Marko <marbar3778@yahoo.com>
This commit is contained in:
Emmanuel T Odeke 2023-04-13 03:22:32 +03:00 committed by GitHub
parent f82cbbbeeb
commit 1c1af09b17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 63 additions and 8 deletions

View File

@ -1,11 +1,17 @@
package textual
package textual_test
import (
"bytes"
"context"
"encoding/json"
"os"
"testing"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/reflect/protoreflect"
"cosmossdk.io/x/tx/internal/testpb"
"cosmossdk.io/x/tx/signing/textual"
)
var intValues = []protoreflect.Value{
@ -22,7 +28,7 @@ var intValues = []protoreflect.Value{
func BenchmarkIntValueRendererFormat(b *testing.B) {
ctx := context.Background()
ivr := new(intValueRenderer)
ivr := textual.NewIntValueRenderer(fieldDescriptorFromName("UINT64"))
b.ResetTimer()
b.ReportAllocs()
@ -49,7 +55,7 @@ var decimalValues = []protoreflect.Value{
func BenchmarkDecimalValueRendererFormat(b *testing.B) {
ctx := context.Background()
dvr := new(decValueRenderer)
dvr := textual.NewDecValueRenderer()
b.ResetTimer()
b.ReportAllocs()
@ -76,7 +82,7 @@ var byteValues = []protoreflect.Value{
func BenchmarkBytesValueRendererFormat(b *testing.B) {
ctx := context.Background()
bvr := new(bytesValueRenderer)
bvr := textual.NewBytesValueRenderer()
b.ResetTimer()
b.ReportAllocs()
@ -88,3 +94,52 @@ func BenchmarkBytesValueRendererFormat(b *testing.B) {
}
}
}
var sink any
func BenchmarkMessageValueRenderer_parseRepeated(b *testing.B) {
ctx := context.Background()
raw, err := os.ReadFile("./internal/testdata/repeated.json")
require.NoError(b, err)
type rendScreens struct {
rend textual.ValueRenderer
screens []textual.Screen
}
var rsL []*rendScreens
var testCases []repeatedJSONTest
err = json.Unmarshal(raw, &testCases)
require.NoError(b, err)
tr, err := textual.NewSignModeHandler(textual.SignModeOptions{CoinMetadataQuerier: mockCoinMetadataQuerier})
for _, tc := range testCases {
rend := textual.NewMessageValueRenderer(tr, (&testpb.Qux{}).ProtoReflect().Descriptor())
require.NoError(b, err)
screens, err := rend.Format(ctx, protoreflect.ValueOf(tc.Proto.ProtoReflect()))
require.NoError(b, err)
require.Equal(b, tc.Screens, screens)
rsL = append(rsL, &rendScreens{
rend: rend,
screens: screens,
})
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, rs := range rsL {
sink, _ = rs.rend.Parse(ctx, rs.screens)
}
}
if sink == nil {
b.Fatal("Benchmark did not run!")
}
// Reset the sink for reuse.
sink = nil
}

View File

@ -261,11 +261,11 @@ func (mr *messageValueRenderer) Parse(ctx context.Context, screens []Screen) (pr
return protoreflect.ValueOfMessage(msg), nil
}
func (mr *messageValueRenderer) parseRepeated(ctx context.Context, screens []Screen, l protoreflect.List, vr ValueRenderer) error {
// <int> <field_kind>
headerRegex := *regexp.MustCompile(`(\d+) .+`)
res := headerRegex.FindAllStringSubmatch(screens[0].Content, -1)
// <int> <field_kind>
var headerRegex = regexp.MustCompile(`(\d+) .+`)
func (mr *messageValueRenderer) parseRepeated(ctx context.Context, screens []Screen, l protoreflect.List, vr ValueRenderer) error {
res := headerRegex.FindAllStringSubmatch(screens[0].Content, -1)
if res == nil {
return errors.New("failed to match <int> <field_kind>")
}