Optimize some string handling (#170)

* Don't use fmt.Sprintf on simple strings
* Use bytes.Buffer in encodeTomlString

name                old time/op    new time/op    delta
Lexer-8                162µs ± 0%     161µs ± 0%   -0.12%
TreeToTomlString-8    19.7µs ± 0%     7.5µs ± 0%  -61.80%

name                old alloc/op   new alloc/op   delta
TreeToTomlString-8    9.75kB ± 0%    4.96kB ± 0%  -49.12%

name                old allocs/op  new allocs/op  delta
TreeToTomlString-8       485 ± 0%        78 ± 0%  -83.92%
This commit is contained in:
Cameron Moore
2017-06-01 23:03:56 -05:00
committed by Thomas Pelletier
parent 5ccdfb18c7
commit a60c71373e
2 changed files with 63 additions and 14 deletions
+15 -14
View File
@@ -13,33 +13,34 @@ import (
// encodes a string to a TOML-compliant string value
func encodeTomlString(value string) string {
result := ""
var b bytes.Buffer
for _, rr := range value {
switch rr {
case '\b':
result += "\\b"
b.WriteString(`\b`)
case '\t':
result += "\\t"
b.WriteString(`\t`)
case '\n':
result += "\\n"
b.WriteString(`\n`)
case '\f':
result += "\\f"
b.WriteString(`\f`)
case '\r':
result += "\\r"
b.WriteString(`\r`)
case '"':
result += "\\\""
b.WriteString(`\"`)
case '\\':
result += "\\\\"
b.WriteString(`\\`)
default:
intRr := uint16(rr)
if intRr < 0x001F {
result += fmt.Sprintf("\\u%0.4X", intRr)
b.WriteString(fmt.Sprintf("\\u%0.4X", intRr))
} else {
result += string(rr)
b.WriteRune(rr)
}
}
}
return result
return b.String()
}
func tomlValueStringRepresentation(v interface{}) (string, error) {
@@ -111,7 +112,7 @@ func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64) (
return bytesCount, err
}
kvRepr := fmt.Sprintf("%s%s = %s\n", indent, k, repr)
kvRepr := indent + k + " = " + repr + "\n"
writtenBytesCount, err := w.Write([]byte(kvRepr))
bytesCount += int64(writtenBytesCount)
if err != nil {
@@ -130,7 +131,7 @@ func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64) (
switch node := v.(type) {
// node has to be of those two types given how keys are sorted above
case *Tree:
tableName := fmt.Sprintf("\n%s[%s]\n", indent, combinedKey)
tableName := "\n" + indent + "[" + combinedKey + "]\n"
writtenBytesCount, err := w.Write([]byte(tableName))
bytesCount += int64(writtenBytesCount)
if err != nil {
@@ -142,7 +143,7 @@ func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64) (
}
case []*Tree:
for _, subTree := range node {
tableArrayName := fmt.Sprintf("\n%s[[%s]]\n", indent, combinedKey)
tableArrayName := "\n" + indent + "[[" + combinedKey + "]]\n"
writtenBytesCount, err := w.Write([]byte(tableArrayName))
bytesCount += int64(writtenBytesCount)
if err != nil {