aboutsummaryrefslogtreecommitdiff
path: root/src/text
diff options
context:
space:
mode:
authorAriel Mashraki <ariel@mashraki.co.il>2019-10-01 01:10:44 +0300
committerEmmanuel Odeke <emm.odeke@gmail.com>2019-10-01 07:16:47 +0000
commit4f13a9c5b1bfc9ec2213d9ee7d9df49661b119dd (patch)
tree22f3ad5b63a4450d83881580c85f379201428b9e /src/text
parentc1635ad8f0bb9fbe5bfbf0a633c78a03930758c4 (diff)
downloadgo-4f13a9c5b1bfc9ec2213d9ee7d9df49661b119dd.tar.gz
go-4f13a9c5b1bfc9ec2213d9ee7d9df49661b119dd.zip
text/template/parse: use strings.Builder in String methods
As mentioned in godoc, strings.Builder is more efficient for concatenating and building strings. Running a simple bench test on VariableNode.String() gives: benchmark old ns/op new ns/op delta BenchmarkParseLarge-8 25676831 24453285 -4.77% BenchmarkVariableString-8 296 115 -61.15% benchmark old allocs new allocs delta BenchmarkVariableString-8 8 3 -62.50% benchmark old bytes new bytes delta BenchmarkVariableString-8 112 72 -35.71% Change-Id: I13c9340080738fcad1edeed859d33ba608e4b05a Reviewed-on: https://go-review.googlesource.com/c/go/+/198078 Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com> Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/text')
-rw-r--r--src/text/template/parse/node.go41
-rw-r--r--src/text/template/parse/parse_test.go16
2 files changed, 38 insertions, 19 deletions
diff --git a/src/text/template/parse/node.go b/src/text/template/parse/node.go
index 2f921be2ec..2eb1af0a95 100644
--- a/src/text/template/parse/node.go
+++ b/src/text/template/parse/node.go
@@ -160,23 +160,23 @@ func (p *PipeNode) append(command *CommandNode) {
}
func (p *PipeNode) String() string {
- s := ""
+ var sb strings.Builder
if len(p.Decl) > 0 {
for i, v := range p.Decl {
if i > 0 {
- s += ", "
+ sb.WriteString(", ")
}
- s += v.String()
+ sb.WriteString(v.String())
}
- s += " := "
+ sb.WriteString(" := ")
}
for i, c := range p.Cmds {
if i > 0 {
- s += " | "
+ sb.WriteString(" | ")
}
- s += c.String()
+ sb.WriteString(c.String())
}
- return s
+ return sb.String()
}
func (p *PipeNode) tree() *Tree {
@@ -249,18 +249,20 @@ func (c *CommandNode) append(arg Node) {
}
func (c *CommandNode) String() string {
- s := ""
+ var sb strings.Builder
for i, arg := range c.Args {
if i > 0 {
- s += " "
+ sb.WriteByte(' ')
}
if arg, ok := arg.(*PipeNode); ok {
- s += "(" + arg.String() + ")"
+ sb.WriteByte('(')
+ sb.WriteString(arg.String())
+ sb.WriteByte(')')
continue
}
- s += arg.String()
+ sb.WriteString(arg.String())
}
- return s
+ return sb.String()
}
func (c *CommandNode) tree() *Tree {
@@ -333,14 +335,14 @@ func (t *Tree) newVariable(pos Pos, ident string) *VariableNode {
}
func (v *VariableNode) String() string {
- s := ""
+ var sb strings.Builder
for i, id := range v.Ident {
if i > 0 {
- s += "."
+ sb.WriteByte('.')
}
- s += id
+ sb.WriteString(id)
}
- return s
+ return sb.String()
}
func (v *VariableNode) tree() *Tree {
@@ -426,11 +428,12 @@ func (t *Tree) newField(pos Pos, ident string) *FieldNode {
}
func (f *FieldNode) String() string {
- s := ""
+ var sb strings.Builder
for _, id := range f.Ident {
- s += "." + id
+ sb.WriteByte('.')
+ sb.WriteString(id)
}
- return s
+ return sb.String()
}
func (f *FieldNode) tree() *Tree {
diff --git a/src/text/template/parse/parse_test.go b/src/text/template/parse/parse_test.go
index 6932cf232e..371de5d67c 100644
--- a/src/text/template/parse/parse_test.go
+++ b/src/text/template/parse/parse_test.go
@@ -553,3 +553,19 @@ func BenchmarkParseLarge(b *testing.B) {
}
}
}
+
+var sink string
+
+func BenchmarkVariableString(b *testing.B) {
+ v := &VariableNode{
+ Ident: []string{"$", "A", "BB", "CCC", "THIS_IS_THE_VARIABLE_BEING_PROCESSED"},
+ }
+ b.ResetTimer()
+ b.ReportAllocs()
+ for i := 0; i < b.N; i++ {
+ sink = v.String()
+ }
+ if sink == "" {
+ b.Fatal("Benchmark was not run")
+ }
+}