transform/urlreplacers: Cache the next position of urlreplacer.prefix

Improved performance due to `bytes.Index` repeated calls

Fixes #5942
This commit is contained in:
HyeonGyu Lee 2019-08-07 00:46:20 +09:00 committed by Bjørn Erik Pedersen
parent 02397e76ce
commit a843ca53b5

View file

@ -41,6 +41,28 @@ type prefix struct {
disabled bool disabled bool
b []byte b []byte
f func(l *absurllexer) f func(l *absurllexer)
nextPos int
}
func (p *prefix) find(bs []byte, start int) bool {
if p.disabled {
return false
}
if p.nextPos == -1 {
idx := bytes.Index(bs[start:], p.b)
if idx == -1 {
p.disabled = true
// Find the closest match
return false
}
p.nextPos = start + idx + len(p.b)
}
return true
} }
func newPrefixState() []*prefix { func newPrefixState() []*prefix {
@ -179,35 +201,28 @@ func (l *absurllexer) replace() {
break break
} }
nextPos := -1
var match *prefix var match *prefix
for _, p := range prefixes { for _, p := range prefixes {
if p.disabled { if !p.find(l.content, l.pos) {
continue continue
} }
idx := bytes.Index(l.content[l.pos:], p.b)
if idx == -1 { if match == nil || p.nextPos < match.nextPos {
p.disabled = true
// Find the closest match
} else if nextPos == -1 || idx < nextPos {
nextPos = idx
match = p match = p
} }
} }
if nextPos == -1 { if match == nil {
// Done! // Done!
l.pos = contentLength l.pos = contentLength
break break
} else { } else {
l.pos += nextPos + len(match.b) l.pos = match.nextPos
match.nextPos = -1
match.f(l) match.f(l)
} }
} }
// Done! // Done!
if l.pos > l.start { if l.pos > l.start {
l.emit() l.emit()