From eff64c563f75c50f8af0ec650e719846efff659b Mon Sep 17 00:00:00 2001 From: Russ Ross Date: Sat, 25 Jun 2011 15:02:46 -0600 Subject: [PATCH] reduce copying for lists --- block.go | 20 +++++++++++--------- html.go | 52 ++++++++++++++++++++++++++++++---------------------- latex.go | 8 ++++++-- markdown.go | 2 +- 4 files changed, 48 insertions(+), 34 deletions(-) diff --git a/block.go b/block.go index abe627d..5ba599f 100644 --- a/block.go +++ b/block.go @@ -882,20 +882,22 @@ func blockOliPrefix(data []byte) int { // parse ordered or unordered list block func blockList(out *bytes.Buffer, rndr *render, data []byte, flags int) int { - var work bytes.Buffer + i := 0 + work := func() bool { + j := 0 + for i < len(data) { + j = blockListItem(out, rndr, data[i:], &flags) + i += j - i, j := 0, 0 - for i < len(data) { - j = blockListItem(&work, rndr, data[i:], &flags) - i += j - - if j == 0 || flags&LIST_ITEM_END_OF_LIST != 0 { - break + if j == 0 || flags&LIST_ITEM_END_OF_LIST != 0 { + break + } } + return true } if rndr.mk.List != nil { - rndr.mk.List(out, work.Bytes(), flags, rndr.mk.Opaque) + rndr.mk.List(out, work, flags, rndr.mk.Opaque) } return i } diff --git a/html.go b/html.go index 2ec7997..e8543b4 100644 --- a/html.go +++ b/html.go @@ -123,39 +123,42 @@ func HtmlTocRenderer(flags int) *Renderer { func attrEscape(out *bytes.Buffer, src []byte) { org := 0 for i, ch := range src { - // doing this check is a bit faster than falling into - // the switch statement. as the compiler improves, this - // should be unnecessary - if ch != '"' && ch != '&' && ch != '<' && ch != '>' { - continue - } - - switch ch { - case '<': + // using if statements is a bit faster than a switch statement. + // as the compiler improves, this should be unnecessary + // this is only worthwhile because attrEscape is the single + // largest CPU user in normal use + if ch == '"' { if i > org { // copy all the normal characters since the last escape out.Write(src[org:i]) } org = i + 1 - out.WriteString("<") - case '>': - if i > org { - out.Write(src[org:i]) - } - org = i + 1 - out.WriteString(">") - case '&': + out.WriteString(""") + continue + } + if ch == '&' { if i > org { out.Write(src[org:i]) } org = i + 1 out.WriteString("&") - case '"': + continue + } + if ch == '<' { if i > org { out.Write(src[org:i]) } org = i + 1 - out.WriteString(""") + out.WriteString("<") + continue + } + if ch == '>' { + if i > org { + out.Write(src[org:i]) + } + org = i + 1 + out.WriteString(">") + continue } } if org < len(src) { @@ -351,8 +354,10 @@ func htmlTableCell(out *bytes.Buffer, text []byte, align int, opaque interface{} out.WriteString("") } -func htmlList(out *bytes.Buffer, text []byte, flags int, opaque interface{}) { - if out.Len() > 0 { +func htmlList(out *bytes.Buffer, text func() bool, flags int, opaque interface{}) { + marker := out.Len() + + if marker > 0 { out.WriteByte('\n') } if flags&LIST_TYPE_ORDERED != 0 { @@ -360,7 +365,10 @@ func htmlList(out *bytes.Buffer, text []byte, flags int, opaque interface{}) { } else { out.WriteString("