Simplify escapeHTML and uncomment it's benchmark Simplify and optimize escapeHTML as per @Ambrevar's suggestion: lean on the fact that we're dealing with bytes: declare a 256-element array with most of it filled with zeros, except for the few slots that need escaping. This avoids some conditionals in a tight loop. Also, uncomment it's benchmark.
Vytautas Ĺ altenis vytas@rtfb.lt
Sat, 08 Oct 2016 17:58:30 +0300
2 files changed,
11 insertions(+),
24 deletions(-)
M
esc.go
→
esc.go
@@ -5,32 +5,21 @@ "html"
"io" ) -type escMap struct { - char byte - seq []byte -} - -var htmlEscaper = []escMap{ - {'&', []byte("&")}, - {'<', []byte("<")}, - {'>', []byte(">")}, - {'"', []byte(""")}, +var htmlEscaper = [256][]byte{ + '&': []byte("&"), + '<': []byte("<"), + '>': []byte(">"), + '"': []byte("""), } func escapeHTML(w io.Writer, s []byte) { var start, end int - var sEnd byte for end < len(s) { - sEnd = s[end] - if sEnd == '&' || sEnd == '<' || sEnd == '>' || sEnd == '"' { - for i := 0; i < len(htmlEscaper); i++ { - if sEnd == htmlEscaper[i].char { - w.Write(s[start:end]) - w.Write(htmlEscaper[i].seq) - start = end + 1 - break - } - } + escSeq := htmlEscaper[s[end]] + if escSeq != nil { + w.Write(s[start:end]) + w.Write(escSeq) + start = end + 1 } end++ }
M
esc_test.go
→
esc_test.go
@@ -23,7 +23,6 @@ }
} } -/* func BenchmarkEscapeHTML(b *testing.B) { tests := [][]byte{ []byte(""),@@ -33,7 +32,7 @@ []byte("This & that."),
[]byte("4 < 5."), []byte("6 > 5."), []byte("Here's a [link] [1] with an ampersand in the URL."), - []byte("Here's a link with an amersand in the link text: [AT&T] [2]."), + []byte("Here's a link with an ampersand in the link text: [AT&T] [2]."), []byte("Here's an inline [link](/script?foo=1&bar=2)."), []byte("Here's an inline [link](</script?foo=1&bar=2>)."), []byte("[1]: http://example.com/?foo=1&bar=2"),@@ -47,4 +46,3 @@ buff.Reset()
} } } -*/