Skip to content

Commit

Permalink
Optimize by minimizing len() calls
Browse files Browse the repository at this point in the history
  • Loading branch information
nelio2k committed Mar 22, 2019
1 parent fd9673b commit ebc2afa
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 53 deletions.
44 changes: 22 additions & 22 deletions fastMatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (m *FastMatcher) leaveValue() error {

tokens := &m.tokens
for {
token, _, err := tokens.Step()
token, _, _, err := tokens.Step()
if err != nil {
return err
}
Expand Down Expand Up @@ -93,7 +93,7 @@ func (m *FastMatcher) literalFromSlot(slot SlotID) FastVal {

slotInfo := m.slots[slot-1]
m.tokens.Seek(slotInfo.start)
token, tokenData, _ := m.tokens.Step()
token, tokenData, _, _ := m.tokens.Step()

if isLiteralToken(token) {
var parser fastLitParser
Expand Down Expand Up @@ -284,7 +284,7 @@ func (m *FastMatcher) matchElems(token tokenType, tokenData []byte, elems map[st
// If this is not the first entry in the object, there should be a
// list delimiter ('c') that shows up in the input first.
if i != 0 {
token, _, err := m.tokens.Step()
token, _, _, err := m.tokens.Step()
if err != nil {
return err
}
Expand All @@ -297,7 +297,7 @@ func (m *FastMatcher) matchElems(token tokenType, tokenData []byte, elems map[st
}
}

token, tokenData, err := m.tokens.Step()
token, tokenData, _, err := m.tokens.Step()
if err != nil {
return err
}
Expand All @@ -314,23 +314,23 @@ func (m *FastMatcher) matchElems(token tokenType, tokenData []byte, elems map[st
panic("expected literal")
}

token, _, err = m.tokens.Step()
token, _, _, err = m.tokens.Step()
if err != nil {
return err
}
if token != tknObjectKeyDelim {
panic("expected object key delimiter")
}

token, tokenData, err = m.tokens.Step()
token, tokenData, tokenDataLen, err := m.tokens.Step()
if err != nil {
return err
}

if keyElem, ok := elems[string(keyBytes)]; ok {
// Run the execution node that applies to this particular
// key of the object.
m.matchExec(token, tokenData, keyElem)
m.matchExec(token, tokenData, tokenDataLen, keyElem)

// Check if running this keys execution has resolved the entirety
// of the expression, if so we can leave immediately.
Expand Down Expand Up @@ -387,7 +387,7 @@ func (m *FastMatcher) matchLoop(token tokenType, tokenData []byte, loop *LoopNod
// If this is not the first entry in the array, there should be a
// list delimiter (',') that shows up in the input first.
if i != 0 {
token, _, err := m.tokens.Step()
token, _, _, err := m.tokens.Step()
if err != nil {
return err
}
Expand All @@ -400,7 +400,7 @@ func (m *FastMatcher) matchLoop(token tokenType, tokenData []byte, loop *LoopNod
}
}

token, tokenData, err := m.tokens.Step()
token, tokenData, tokenDataLen, err := m.tokens.Step()
if err != nil {
return err
}
Expand All @@ -413,7 +413,7 @@ func (m *FastMatcher) matchLoop(token tokenType, tokenData []byte, loop *LoopNod
m.buckets.ResetNode(loopBucketIdx)

// Run the execution node for this element of the array.
err = m.matchExec(token, tokenData, loop.Node)
err = m.matchExec(token, tokenData, tokenDataLen, loop.Node)
if err != nil {
return err
}
Expand Down Expand Up @@ -484,7 +484,7 @@ func (m *FastMatcher) matchAfter(node *AfterNode) error {
slotInfo := m.slots[slot.Slot-1]

m.tokens.Seek(slotInfo.start)
token, tokenData, err := m.tokens.Step()
token, tokenData, _, err := m.tokens.Step()

// run the loop matcher
err = m.matchLoop(token, tokenData, &loop)
Expand Down Expand Up @@ -517,14 +517,14 @@ func (m *FastMatcher) matchAfter(node *AfterNode) error {
return nil
}

func (m *FastMatcher) matchExec(token tokenType, tokenData []byte, node *ExecNode) error {
func (m *FastMatcher) matchExec(token tokenType, tokenData []byte, tokenDataLen int, node *ExecNode) error {
startPos := m.tokens.Position()
endPos := -1

// The start position needs to include the token we already parsed, so lets
// back up our position based on how long that is...
// TODO(brett19): We should probably find a more optimal way to handle this...
startPos -= len(tokenData)
startPos -= tokenDataLen

if isLiteralToken(token) {
var litParse fastLitParser
Expand Down Expand Up @@ -646,7 +646,7 @@ func (m *FastMatcher) matchObjectOrArray(token tokenType, tokenData []byte, node
// If this is not the first entry in the object, there should be a
// list delimiter ('c') that shows up in the input first.
if i != 0 {
token, _, err := m.tokens.Step()
token, _, _, err := m.tokens.Step()
if err != nil {
return err, true
}
Expand All @@ -666,7 +666,7 @@ func (m *FastMatcher) matchObjectOrArray(token tokenType, tokenData []byte, node
}
}

token, tokenData, err := m.tokens.Step()
token, tokenData, tokenDataLen, err := m.tokens.Step()
if err != nil {
return err, true
}
Expand All @@ -680,9 +680,9 @@ func (m *FastMatcher) matchObjectOrArray(token tokenType, tokenData []byte, node
var keyBytes []byte
switch token {
case tknString:
keyBytes = keyLitParse.ParseString(tokenData)
keyBytes = keyLitParse.ParseStringWLen(tokenData, tokenDataLen)
case tknEscString:
keyBytes = keyLitParse.ParseEscString(tokenData)
keyBytes = keyLitParse.ParseEscStringWLen(tokenData, tokenDataLen)
case tknArrayStart:
// Do nothing
case tknObjectStart:
Expand All @@ -698,7 +698,7 @@ func (m *FastMatcher) matchObjectOrArray(token tokenType, tokenData []byte, node
// Fake a key element by using the array index, and use the key as the actual value, tokenData
keyString = fmt.Sprintf("[%d]", arrayIndex)
} else {
token, tokenData, err = m.tokens.Step()
token, tokenData, tokenDataLen, err = m.tokens.Step()
if err != nil {
return err, true
}
Expand All @@ -707,7 +707,7 @@ func (m *FastMatcher) matchObjectOrArray(token tokenType, tokenData []byte, node
panic(fmt.Sprintf("expected object key delimiter: got %v, %v", token, string(tokenData)))
}

token, tokenData, err = m.tokens.Step()
token, tokenData, tokenDataLen, err = m.tokens.Step()
if err != nil {
return err, true
}
Expand All @@ -717,7 +717,7 @@ func (m *FastMatcher) matchObjectOrArray(token tokenType, tokenData []byte, node
if keyElem, ok := node.Elems[keyString]; ok {
// Run the execution node that applies to this particular
// key of the object.
m.matchExec(token, tokenData, keyElem)
m.matchExec(token, tokenData, tokenDataLen, keyElem)

// Check if running this keys execution has resolved the entirety
// of the expression, if so we can leave immediately.
Expand All @@ -740,12 +740,12 @@ func (m *FastMatcher) Match(data []byte) (bool, error) {
return false, nil
}

token, tokenData, err := m.tokens.Step()
token, tokenData, tokenDataLen, err := m.tokens.Step()
if err != nil {
return false, err
}

err = m.matchExec(token, tokenData, m.def.ParseNode)
err = m.matchExec(token, tokenData, tokenDataLen, m.def.ParseNode)
if err != nil {
return false, err
}
Expand Down
9 changes: 9 additions & 0 deletions fastlitparse.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,20 @@ func (p *fastLitParser) ParseString(bytes []byte) []byte {
return bytes[1 : len(bytes)-1]
}

func (p *fastLitParser) ParseStringWLen(bytes []byte, size int) []byte {
return bytes[1 : size-1]
}

func (p *fastLitParser) ParseEscString(bytes []byte) []byte {
bytesOut, _ := unescapeJsonString(bytes[1:len(bytes)-1], p.tmpBytesData[:])
return bytesOut
}

func (p *fastLitParser) ParseEscStringWLen(bytes []byte, size int) []byte {
bytesOut, _ := unescapeJsonString(bytes[1:size-1], p.tmpBytesData[:])
return bytesOut
}

func (p *fastLitParser) Parse(token tokenType, bytes []byte) FastVal {
switch token {
case tknString:
Expand Down
Loading

0 comments on commit ebc2afa

Please sign in to comment.