Commit 86cd6c2e authored by Ariel Mashraki's avatar Ariel Mashraki Committed by Emmanuel Odeke

text/template/parse: use strings.Builder in Chain and List nodes

This CL is a continuation of 198078. Benchmark output:

benchmark                     old ns/op     new ns/op     delta
BenchmarkParseLarge-8         24759165      24516563      -0.98%
BenchmarkVariableString-8     115           115           +0.00%
BenchmarkListString-8         924           680           -26.41%

benchmark                     old allocs     new allocs     delta
BenchmarkVariableString-8     3              3              +0.00%
BenchmarkListString-8         14             13             -7.14%

benchmark                     old bytes     new bytes     delta
BenchmarkVariableString-8     72            72            +0.00%
BenchmarkListString-8         512           424           -17.19%

Change-Id: I9ec48fe4832437c556a5fa94d4cbf6e29e28d944
Reviewed-on: https://go-review.googlesource.com/c/go/+/198080Reviewed-by: default avatarEmmanuel Odeke <emm.odeke@gmail.com>
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 09c9bced
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
package parse package parse
import ( import (
"bytes"
"fmt" "fmt"
"strconv" "strconv"
"strings" "strings"
...@@ -94,11 +93,11 @@ func (l *ListNode) tree() *Tree { ...@@ -94,11 +93,11 @@ func (l *ListNode) tree() *Tree {
} }
func (l *ListNode) String() string { func (l *ListNode) String() string {
b := new(bytes.Buffer) var sb strings.Builder
for _, n := range l.Nodes { for _, n := range l.Nodes {
fmt.Fprint(b, n) sb.WriteString(n.String())
} }
return b.String() return sb.String()
} }
func (l *ListNode) CopyList() *ListNode { func (l *ListNode) CopyList() *ListNode {
...@@ -472,14 +471,19 @@ func (c *ChainNode) Add(field string) { ...@@ -472,14 +471,19 @@ func (c *ChainNode) Add(field string) {
} }
func (c *ChainNode) String() string { func (c *ChainNode) String() string {
s := c.Node.String() var sb strings.Builder
if _, ok := c.Node.(*PipeNode); ok { if _, ok := c.Node.(*PipeNode); ok {
s = "(" + s + ")" sb.WriteByte('(')
sb.WriteString(c.Node.String())
sb.WriteByte(')')
} else {
sb.WriteString(c.Node.String())
} }
for _, field := range c.Field { for _, field := range c.Field {
s += "." + field sb.WriteByte('.')
sb.WriteString(field)
} }
return s return sb.String()
} }
func (c *ChainNode) tree() *Tree { func (c *ChainNode) tree() *Tree {
......
...@@ -554,7 +554,7 @@ func BenchmarkParseLarge(b *testing.B) { ...@@ -554,7 +554,7 @@ func BenchmarkParseLarge(b *testing.B) {
} }
} }
var sink string var sinkv, sinkl string
func BenchmarkVariableString(b *testing.B) { func BenchmarkVariableString(b *testing.B) {
v := &VariableNode{ v := &VariableNode{
...@@ -563,9 +563,25 @@ func BenchmarkVariableString(b *testing.B) { ...@@ -563,9 +563,25 @@ func BenchmarkVariableString(b *testing.B) {
b.ResetTimer() b.ResetTimer()
b.ReportAllocs() b.ReportAllocs()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
sink = v.String() sinkv = v.String()
} }
if sink == "" { if sinkv == "" {
b.Fatal("Benchmark was not run")
}
}
func BenchmarkListString(b *testing.B) {
text := `{{ (printf .Field1.Field2.Field3).Value }}`
tree, err := New("bench").Parse(text, "", "", make(map[string]*Tree), builtins)
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
sinkl = tree.Root.String()
}
if sinkl == "" {
b.Fatal("Benchmark was not run") b.Fatal("Benchmark was not run")
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment