From 461803619bb97f3b6e50248dccae978ca17f8d27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vytautas=20=C5=A0altenis?= Date: Sat, 8 Oct 2016 17:58:30 +0300 Subject: [PATCH] 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. --- esc.go | 31 ++++++++++--------------------- esc_test.go | 4 +--- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/esc.go b/esc.go index 8fa5a79..6385f27 100644 --- a/esc.go +++ b/esc.go @@ -5,32 +5,21 @@ import ( "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++ } diff --git a/esc_test.go b/esc_test.go index b1aca63..b3b7a07 100644 --- a/esc_test.go +++ b/esc_test.go @@ -23,7 +23,6 @@ func TestEsc(t *testing.T) { } } -/* func BenchmarkEscapeHTML(b *testing.B) { tests := [][]byte{ []byte(""), @@ -33,7 +32,7 @@ func BenchmarkEscapeHTML(b *testing.B) { []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]()."), []byte("[1]: http://example.com/?foo=1&bar=2"), @@ -47,4 +46,3 @@ func BenchmarkEscapeHTML(b *testing.B) { } } } -*/