shithub: hugo

Download patch

ref: 3d9c4f513b0443648d7e88995e351df1739646d2
parent: 250ebc1db5be13063878b178eaad11c4361b7a9d
author: Bjørn Erik Pedersen <[email protected]>
date: Sat Jun 3 04:32:52 EDT 2017

parser: Add BenchmarkFrontmatterTags

The list handling is surprisingly expensive:

```
▶ go test -run="NONE" -bench="BenchmarkFrontmatterTags" -test.benchmem=true ./parser | prettybench
PASS
benchmark                               iter         time/iter   bytes alloc           allocs
---------                               ----         ---------   -----------           ------
BenchmarkFrontmatterTags/JSON:1-4    1000000     2039.00 ns/op      912 B/op     20 allocs/op
BenchmarkFrontmatterTags/JSON:11-4    300000     5202.00 ns/op     1640 B/op     44 allocs/op
BenchmarkFrontmatterTags/JSON:21-4    200000     7993.00 ns/op     2392 B/op     65 allocs/op
BenchmarkFrontmatterTags/YAML:1-4     200000     9359.00 ns/op     5928 B/op     66 allocs/op
BenchmarkFrontmatterTags/YAML:11-4    100000    21218.00 ns/op     8408 B/op    140 allocs/op
BenchmarkFrontmatterTags/YAML:21-4     50000    32852.00 ns/op    10920 B/op    211 allocs/op
BenchmarkFrontmatterTags/TOML:1-4     100000    21505.00 ns/op     9231 B/op    173 allocs/op
BenchmarkFrontmatterTags/TOML:11-4     20000    82919.00 ns/op    19808 B/op    625 allocs/op
BenchmarkFrontmatterTags/TOML:21-4     10000   141847.00 ns/op    31200 B/op   1106 allocs/op
ok      github.com/spf13/hugo/parser    17.890s
```

See #3464

--- a/parser/frontmatter_test.go
+++ b/parser/frontmatter_test.go
@@ -15,7 +15,9 @@
 
 import (
 	"bytes"
+	"fmt"
 	"reflect"
+	"strings"
 	"testing"
 )
 
@@ -316,4 +318,72 @@
 			t.Errorf("[%d] given %q\nwant: %q\n got: %q", i, c.input, c.want, res)
 		}
 	}
+}
+
+func BenchmarkFrontmatterTags(b *testing.B) {
+
+	for _, frontmatter := range []string{"JSON", "YAML", "TOML"} {
+		for i := 1; i < 30; i += 10 {
+			doBenchmarkFrontmatter(b, frontmatter, i)
+		}
+	}
+}
+
+func doBenchmarkFrontmatter(b *testing.B, fileformat string, numTags int) {
+	yamlTemplate := `---
+name: "Tags"
+tags:
+%s
+---
+`
+	tomlTemplate := `+++
+name = "Tags"
+tags = %s
++++
+`
+
+	jsonTemplate := `{
+	"name": "Tags",
+	"tags": [
+		%s
+	]
+}`
+	name := fmt.Sprintf("%s:%d", fileformat, numTags)
+	b.Run(name, func(b *testing.B) {
+		tags := make([]string, numTags)
+		var (
+			tagsStr             string
+			frontmatterTemplate string
+		)
+		for i := 0; i < numTags; i++ {
+			tags[i] = fmt.Sprintf("Hugo %d", i+1)
+		}
+		if fileformat == "TOML" {
+			frontmatterTemplate = tomlTemplate
+			tagsStr = strings.Replace(fmt.Sprintf("%q", tags), " ", ", ", -1)
+		} else if fileformat == "JSON" {
+			frontmatterTemplate = jsonTemplate
+			tagsStr = strings.Replace(fmt.Sprintf("%q", tags), " ", ", ", -1)
+		} else {
+			frontmatterTemplate = yamlTemplate
+			for _, tag := range tags {
+				tagsStr += "\n- " + tag
+			}
+		}
+
+		frontmatter := fmt.Sprintf(frontmatterTemplate, tagsStr)
+
+		p := page{frontmatter: []byte(frontmatter)}
+
+		b.ResetTimer()
+		for i := 0; i < b.N; i++ {
+			meta, err := p.Metadata()
+			if err != nil {
+				b.Fatal(err)
+			}
+			if meta == nil {
+				b.Fatal("Meta is nil")
+			}
+		}
+	})
 }