hugolib: Rewrite replaceDivider to reduce memory allocation
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 14 Aug 2017 07:24:38 +0000 (09:24 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 14 Aug 2017 07:42:55 +0000 (09:42 +0200)
```bash
name              old time/op    new time/op    delta
ReplaceDivider-4   9.76µs ±105%    7.96µs ±24%     ~     (p=0.690 n=5+5)

name              old alloc/op   new alloc/op   delta
ReplaceDivider-4    3.46kB ± 0%    1.54kB ± 0%  -55.56%  (p=0.008 n=5+5)

name              old allocs/op  new allocs/op  delta
ReplaceDivider-4      6.00 ± 0%      1.00 ± 0%  -83.33%  (p=0.008 n=5+5)
```

hugolib/page.go
hugolib/page_test.go

index b5d13d4db2cfeeebfff4938307e8a6c3789c684f..5de976bd4923c1836ebc367f93bcd9bc76b7f6b8 100644 (file)
@@ -18,6 +18,7 @@ import (
        "errors"
        "fmt"
        "reflect"
+       "unicode"
 
        "github.com/bep/gitmap"
 
@@ -488,17 +489,23 @@ var (
 // whether the contentis truncated or not.
 // Note: The content slice will be modified if needed.
 func replaceDivider(content, from, to []byte) ([]byte, bool) {
-       sections := bytes.Split(content, from)
+       dividerIdx := bytes.Index(content, from)
+       if dividerIdx == -1 {
+               return content, false
+       }
+
+       afterSummary := content[dividerIdx+len(from):]
 
        // If the raw content has nothing but whitespace after the summary
        // marker then the page shouldn't be marked as truncated.  This check
        // is simplest against the raw content because different markup engines
        // (rst and asciidoc in particular) add div and p elements after the
        // summary marker.
-       truncated := (len(sections) == 2 &&
-               len(bytes.Trim(sections[1], " \n\r")) > 0)
+       truncated := bytes.IndexFunc(afterSummary, func(r rune) bool { return !unicode.IsSpace(r) }) != -1
+
+       content = append(content[:dividerIdx], append(to, afterSummary...)...)
 
-       return bytes.Join(sections, to), truncated
+       return content, truncated
 
 }
 
index cc2ab9662ca0847758eea584be4de8826ce2cb02..7723c02c4431379b2ff4f2f4ada30976c43e3598 100644 (file)
@@ -1107,7 +1107,7 @@ func TestReplaceDivider(t *testing.T) {
                expectedTruncated bool
        }{
                {"none", "a", "b", "none", false},
-               {"summary divider content", "divider", "HUGO", "summary HUGO content", true},
+               {"summary <!--more--> content", "<!--more-->", "HUGO", "summary HUGO content", true},
                {"summary\n\ndivider", "divider", "HUGO", "summary\n\nHUGO", false},
                {"summary\n\ndivider\n\r", "divider", "HUGO", "summary\n\nHUGO\n\r", false},
        }