1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
// +build go1.7
package errors
import (
"fmt"
"testing"
stderrors "errors"
)
func noErrors(at, depth int) error {
if at >= depth {
return stderrors.New("no error")
}
return noErrors(at+1, depth)
}
func yesErrors(at, depth int) error {
if at >= depth {
return New("ye error")
}
return yesErrors(at+1, depth)
}
// GlobalE is an exported global to store the result of benchmark results,
// preventing the compiler from optimising the benchmark functions away.
var GlobalE interface{}
func BenchmarkErrors(b *testing.B) {
type run struct {
stack int
std bool
}
runs := []run{
{10, false},
{10, true},
{100, false},
{100, true},
{1000, false},
{1000, true},
}
for _, r := range runs {
part := "pkg/errors"
if r.std {
part = "errors"
}
name := fmt.Sprintf("%s-stack-%d", part, r.stack)
b.Run(name, func(b *testing.B) {
var err error
f := yesErrors
if r.std {
f = noErrors
}
b.ReportAllocs()
for i := 0; i < b.N; i++ {
err = f(0, r.stack)
}
b.StopTimer()
GlobalE = err
})
}
}
func BenchmarkStackFormatting(b *testing.B) {
type run struct {
stack int
format string
}
runs := []run{
{10, "%s"},
{10, "%v"},
{10, "%+v"},
{30, "%s"},
{30, "%v"},
{30, "%+v"},
{60, "%s"},
{60, "%v"},
{60, "%+v"},
}
var stackStr string
for _, r := range runs {
name := fmt.Sprintf("%s-stack-%d", r.format, r.stack)
b.Run(name, func(b *testing.B) {
err := yesErrors(0, r.stack)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
stackStr = fmt.Sprintf(r.format, err)
}
b.StopTimer()
})
}
for _, r := range runs {
name := fmt.Sprintf("%s-stacktrace-%d", r.format, r.stack)
b.Run(name, func(b *testing.B) {
err := yesErrors(0, r.stack)
st := err.(*fundamental).stack.StackTrace()
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
stackStr = fmt.Sprintf(r.format, st)
}
b.StopTimer()
})
}
GlobalE = stackStr
}
|