Skip to content

Commit

Permalink
Optimize tag value parsing
Browse files Browse the repository at this point in the history
```
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]>
  • Loading branch information
sylr committed Jul 17, 2024
1 parent e3a2994 commit f725b98
Showing 1 changed file with 22 additions and 1 deletion.
23 changes: 22 additions & 1 deletion tag_value.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,36 @@ func (tv *TagValue) init(tag Tag, value []byte) {
}

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

// Most of the Fix tags are 4 or less characters long, so we can optimize
// for that by checking the 5 first characters without looping over the
// whole byte slice.
if len(rawFieldBytes) >= 5 {
if rawFieldBytes[1] == '=' {
sepIndex = 1
goto PARSE
} else if rawFieldBytes[2] == '=' {
sepIndex = 2
goto PARSE
} else if rawFieldBytes[3] == '=' {
sepIndex = 3
goto PARSE
} else if rawFieldBytes[4] == '=' {
sepIndex = 4
goto PARSE
}
}

sepIndex = bytes.IndexByte(rawFieldBytes, '=')
switch sepIndex {
case -1:
return fmt.Errorf("tagValue.Parse: No '=' in '%s'", rawFieldBytes)
case 0:
return fmt.Errorf("tagValue.Parse: No tag in '%s'", rawFieldBytes)
}

PARSE:
parsedTag, err := atoi(rawFieldBytes[:sepIndex])
if err != nil {
return fmt.Errorf("tagValue.Parse: %s", err.Error())
Expand Down

0 comments on commit f725b98

Please sign in to comment.