Performance optimizations

This commit is contained in:
yuin 2019-05-01 20:43:10 +09:00
parent 987f65f813
commit e7cef1b7ca
2 changed files with 22 additions and 25 deletions

View file

@ -121,9 +121,9 @@ Though goldmark builds clean extensible AST structure and get full compliance wi
Commonmark, it is resonably fast and less memory consumption. Commonmark, it is resonably fast and less memory consumption.
``` ```
BenchmarkGoldMark-4 200 7981524 ns/op 2485650 B/op 15716 allocs/op BenchmarkGoldMark-4 200 7176000 ns/op 2482660 B/op 15597 allocs/op
BenchmarkGolangCommonMark-4 200 8609737 ns/op 3053758 B/op 18681 allocs/op BenchmarkGolangCommonMark-4 200 7874817 ns/op 3053775 B/op 18682 allocs/op
BenchmarkBlackFriday-4 200 6311112 ns/op 3356762 B/op 17481 allocs/op BenchmarkBlackFriday-4 300 5871891 ns/op 3356419 B/op 17481 allocs/op
``` ```
Donation Donation

View file

@ -377,16 +377,21 @@ func EscapeHTMLByte(b byte) []byte {
// EscapeHTML escapes characters that should be escaped in HTML text. // EscapeHTML escapes characters that should be escaped in HTML text.
func EscapeHTML(v []byte) []byte { func EscapeHTML(v []byte) []byte {
result := make([]byte, 0, len(v)+10) cob := NewCopyOnWriteBuffer(v)
for _, c := range v { n := 0
for i := 0; i < len(v); i++ {
c := v[i]
escaped := htmlEscapeTable[c] escaped := htmlEscapeTable[c]
if escaped != nil { if escaped != nil {
result = append(result, escaped...) cob.Write(v[n:i])
} else { cob.Write(escaped)
result = append(result, c) n = i + 1
} }
} }
return result if cob.IsCopied() {
cob.Write(v[n:len(v)])
}
return cob.Bytes()
} }
// UnescapePunctuations unescapes blackslash escaped punctuations. // UnescapePunctuations unescapes blackslash escaped punctuations.
@ -508,17 +513,9 @@ func URLEscape(v []byte, resolveReference bool) []byte {
v = ResolveNumericReferences(v) v = ResolveNumericReferences(v)
v = ResolveEntityNames(v) v = ResolveEntityNames(v)
} }
ret := v cob := NewCopyOnWriteBuffer(v)
changed := false
limit := len(v) limit := len(v)
n := 0 n := 0
add := func(b []byte) {
if !changed {
ret = make([]byte, 0, len(v)+20)
changed = true
}
ret = append(ret, b...)
}
for i := 0; i < limit; { for i := 0; i < limit; {
c := v[i] c := v[i]
@ -536,21 +533,21 @@ func URLEscape(v []byte, resolveReference bool) []byte {
continue continue
} }
if c == ' ' { if c == ' ' {
add(v[n:i]) cob.Write(v[n:i])
add(htmlSpace) cob.Write(htmlSpace)
i++ i++
n = i n = i
continue continue
} }
add(v[n:i]) cob.Write(v[n:i])
add([]byte(url.QueryEscape(string(v[i : i+int(u8len)])))) cob.Write(StringToReadOnlyBytes(url.QueryEscape(string(v[i : i+int(u8len)]))))
i += int(u8len) i += int(u8len)
n = i n = i
} }
if changed { if cob.IsCopied() {
add(v[n:len(v)]) cob.Write(v[n:len(v)])
} }
return ret return cob.Bytes()
} }
// FindAttributeIndex searchs // FindAttributeIndex searchs