From a843ca53b5e0f29df9535fa0e88408a63cdc2cd7 Mon Sep 17 00:00:00 2001 From: HyeonGyu Lee Date: Wed, 7 Aug 2019 00:46:20 +0900 Subject: [PATCH] transform/urlreplacers: Cache the next position of `urlreplacer.prefix` Improved performance due to `bytes.Index` repeated calls Fixes #5942 --- transform/urlreplacers/absurlreplacer.go | 39 ++++++++++++++++-------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/transform/urlreplacers/absurlreplacer.go b/transform/urlreplacers/absurlreplacer.go index 545df914a..3fef013fb 100644 --- a/transform/urlreplacers/absurlreplacer.go +++ b/transform/urlreplacers/absurlreplacer.go @@ -41,6 +41,28 @@ type prefix struct { disabled bool b []byte 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 { @@ -179,35 +201,28 @@ func (l *absurllexer) replace() { break } - nextPos := -1 - var match *prefix for _, p := range prefixes { - if p.disabled { + if !p.find(l.content, l.pos) { continue } - idx := bytes.Index(l.content[l.pos:], p.b) - if idx == -1 { - p.disabled = true - // Find the closest match - } else if nextPos == -1 || idx < nextPos { - nextPos = idx + if match == nil || p.nextPos < match.nextPos { match = p } } - if nextPos == -1 { + if match == nil { // Done! l.pos = contentLength break } else { - l.pos += nextPos + len(match.b) + l.pos = match.nextPos + match.nextPos = -1 match.f(l) } } - // Done! if l.pos > l.start { l.emit()