Skip to content

Commit f725b98

Browse files
committed
Optimize tag value parsing
``` goos: darwin goarch: arm64 pkg: github.com/quickfixgo/quickfix │ old │ new-no-indexbyte │ │ sec/op │ sec/op vs base │ ParseMessage-8 695.2n ± 1% 628.2n ± 1% -9.64% (p=0.000 n=20) ``` Signed-off-by: Sylvain Rabot <[email protected]>
1 parent e3a2994 commit f725b98

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

Diff for: tag_value.go

+22-1
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,36 @@ func (tv *TagValue) init(tag Tag, value []byte) {
3939
}
4040

4141
func (tv *TagValue) parse(rawFieldBytes []byte) error {
42-
sepIndex := bytes.IndexByte(rawFieldBytes, '=')
42+
var sepIndex int
4343

44+
// Most of the Fix tags are 4 or less characters long, so we can optimize
45+
// for that by checking the 5 first characters without looping over the
46+
// whole byte slice.
47+
if len(rawFieldBytes) >= 5 {
48+
if rawFieldBytes[1] == '=' {
49+
sepIndex = 1
50+
goto PARSE
51+
} else if rawFieldBytes[2] == '=' {
52+
sepIndex = 2
53+
goto PARSE
54+
} else if rawFieldBytes[3] == '=' {
55+
sepIndex = 3
56+
goto PARSE
57+
} else if rawFieldBytes[4] == '=' {
58+
sepIndex = 4
59+
goto PARSE
60+
}
61+
}
62+
63+
sepIndex = bytes.IndexByte(rawFieldBytes, '=')
4464
switch sepIndex {
4565
case -1:
4666
return fmt.Errorf("tagValue.Parse: No '=' in '%s'", rawFieldBytes)
4767
case 0:
4868
return fmt.Errorf("tagValue.Parse: No tag in '%s'", rawFieldBytes)
4969
}
5070

71+
PARSE:
5172
parsedTag, err := atoi(rawFieldBytes[:sepIndex])
5273
if err != nil {
5374
return fmt.Errorf("tagValue.Parse: %s", err.Error())

0 commit comments

Comments
 (0)