Skip to content

Commit 8e45df6

Browse files
author
Dean Karn
committed
tunes error string building performance
1 parent 9e7cf45 commit 8e45df6

File tree

3 files changed

+47
-13
lines changed

3 files changed

+47
-13
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
GOCMD=go
1+
GOCMD=GO111MODULE=on go
22

33
linters-install:
44
@golangci-lint --version >/dev/null 2>&1 || { \

benchmarks_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package errors
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func BenchmarkError(b *testing.B) {
8+
err := New("base error")
9+
for i := 0; i < b.N; i++ {
10+
_ = err.Error()
11+
}
12+
}
13+
14+
func BenchmarkErrorParallel(b *testing.B) {
15+
err := New("base error")
16+
b.RunParallel(func(pb *testing.PB) {
17+
for pb.Next() {
18+
_ = err.Error()
19+
}
20+
})
21+
}

chain.go

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package errors
22

33
import (
44
"fmt"
5+
"strconv"
56
"strings"
67
)
78

@@ -31,13 +32,16 @@ type Chain []*Link
3132

3233
// Error returns the formatted error string
3334
func (c Chain) Error() string {
34-
lines := make([]string, 0, len(c))
35+
b := make([]byte, 0, len(c)*128)
36+
3537
//source=<source> <prefix>: <error> tag=value tag2=value2 types=type1,type2
3638
for i := len(c) - 1; i >= 0; i-- {
37-
line := c[i].formatError()
38-
lines = append(lines, line)
39+
b = c[i].formatError(b)
40+
if i > 0 {
41+
b = append(b, '\n')
42+
}
3943
}
40-
return strings.Join(lines, "\n")
44+
return string(b)
4145
}
4246

4347
// Link contains a single error entry, unless it's the top level error, in
@@ -61,28 +65,37 @@ type Link struct {
6165
}
6266

6367
// formatError prints a single Links error
64-
func (l *Link) formatError() string {
65-
line := fmt.Sprintf("source=%s: %s:%d ", l.Source.Function(), l.Source.File(), l.Source.Line())
68+
func (l *Link) formatError(b []byte) []byte {
69+
b = append(b, "source="...)
70+
b = append(b, l.Source.Function()...)
71+
b = append(b, ": "...)
72+
b = append(b, l.Source.File()...)
73+
b = append(b, ':')
74+
strconv.AppendInt(b, int64(l.Source.Line()), 10)
6675

6776
if l.Prefix != "" {
68-
line += l.Prefix
77+
b = append(b, l.Prefix...)
6978
}
7079

7180
if _, ok := l.Err.(Chain); !ok {
7281
if l.Prefix != "" {
73-
line += ": "
82+
b = append(b, ": "...)
7483
}
75-
line += l.Err.Error()
84+
b = append(b, l.Err.Error()...)
7685
}
7786

7887
for _, tag := range l.Tags {
79-
line += fmt.Sprintf(" %s=%v", tag.Key, tag.Value)
88+
b = append(b, ' ')
89+
b = append(b, tag.Key...)
90+
b = append(b, '=')
91+
b = append(b, fmt.Sprintf("%v", tag.Value)...)
8092
}
8193

8294
if len(l.Types) > 0 {
83-
line += " types=" + strings.Join(l.Types, ",")
95+
b = append(b, " types="...)
96+
b = append(b, strings.Join(l.Types, ",")...)
8497
}
85-
return line
98+
return b
8699
}
87100

88101
// helper method to get the current *Link from the top level

0 commit comments

Comments
 (0)