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.
This commit is contained in:
Vytautas Šaltenis 2016-10-08 17:58:30 +03:00
parent d9ffdb7464
commit 461803619b
2 changed files with 11 additions and 24 deletions

31
esc.go
View File

@ -5,32 +5,21 @@ import (
"io" "io"
) )
type escMap struct { var htmlEscaper = [256][]byte{
char byte '&': []byte("&"),
seq []byte '<': []byte("&lt;"),
} '>': []byte("&gt;"),
'"': []byte("&quot;"),
var htmlEscaper = []escMap{
{'&', []byte("&amp;")},
{'<', []byte("&lt;")},
{'>', []byte("&gt;")},
{'"', []byte("&quot;")},
} }
func escapeHTML(w io.Writer, s []byte) { func escapeHTML(w io.Writer, s []byte) {
var start, end int var start, end int
var sEnd byte
for end < len(s) { for end < len(s) {
sEnd = s[end] escSeq := htmlEscaper[s[end]]
if sEnd == '&' || sEnd == '<' || sEnd == '>' || sEnd == '"' { if escSeq != nil {
for i := 0; i < len(htmlEscaper); i++ { w.Write(s[start:end])
if sEnd == htmlEscaper[i].char { w.Write(escSeq)
w.Write(s[start:end]) start = end + 1
w.Write(htmlEscaper[i].seq)
start = end + 1
break
}
}
} }
end++ end++
} }

View File

@ -23,7 +23,6 @@ func TestEsc(t *testing.T) {
} }
} }
/*
func BenchmarkEscapeHTML(b *testing.B) { func BenchmarkEscapeHTML(b *testing.B) {
tests := [][]byte{ tests := [][]byte{
[]byte(""), []byte(""),
@ -33,7 +32,7 @@ func BenchmarkEscapeHTML(b *testing.B) {
[]byte("4 < 5."), []byte("4 < 5."),
[]byte("6 > 5."), []byte("6 > 5."),
[]byte("Here's a [link] [1] with an ampersand in the URL."), []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("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"), []byte("[1]: http://example.com/?foo=1&bar=2"),
@ -47,4 +46,3 @@ func BenchmarkEscapeHTML(b *testing.B) {
} }
} }
} }
*/