Skip to content
This repository was archived by the owner on Dec 1, 2021. It is now read-only.

Commit e9933c1

Browse files
committed
Restore performance improvements from #150
1 parent ee1923e commit e9933c1

File tree

1 file changed

+32
-4
lines changed

1 file changed

+32
-4
lines changed

stack.go

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package errors
22

33
import (
4+
"bytes"
45
"fmt"
56
"io"
67
"path"
@@ -98,23 +99,50 @@ type StackTrace []Frame
9899
//
99100
// %+v Prints filename, function, and line number for each Frame in the stack.
100101
func (st StackTrace) Format(s fmt.State, verb rune) {
102+
var b bytes.Buffer
101103
switch verb {
102104
case 'v':
103105
switch {
104106
case s.Flag('+'):
107+
b.Grow(len(st) * stackMinLen)
105108
for _, f := range st {
106-
fmt.Fprintf(s, "\n%+v", f)
109+
b.WriteByte('\n')
110+
f.format(&b, s, verb)
107111
}
108112
case s.Flag('#'):
109-
fmt.Fprintf(s, "%#v", []Frame(st))
113+
fmt.Fprintf(&b, "%#v", []Frame(st))
110114
default:
111-
fmt.Fprintf(s, "%v", []Frame(st))
115+
st.formatSlice(&b, s, verb)
112116
}
113117
case 's':
114-
fmt.Fprintf(s, "%s", []Frame(st))
118+
st.formatSlice(&b, s, verb)
115119
}
120+
io.Copy(s, &b)
116121
}
117122

123+
// formatSlice will format this StackTrace into the given buffer as a slice of
124+
// Frame, only valid when called with '%s' or '%v'.
125+
func (st StackTrace) formatSlice(b *bytes.Buffer, s fmt.State, verb rune) {
126+
b.WriteByte('[')
127+
if len(st) == 0 {
128+
b.WriteByte(']')
129+
return
130+
}
131+
132+
b.Grow(len(st) * (stackMinLen / 4))
133+
st[0].format(b, s, verb)
134+
for _, fr := range st[1:] {
135+
b.WriteByte(' ')
136+
fr.format(b, s, verb)
137+
}
138+
b.WriteByte(']')
139+
}
140+
141+
// stackMinLen is a best-guess at the minimum length of a stack trace. It
142+
// doesn't need to be exact, just give a good enough head start for the buffer
143+
// to avoid the expensive early growth.
144+
const stackMinLen = 96
145+
118146
// stack represents a stack of program counters.
119147
type stack []uintptr
120148

0 commit comments

Comments
 (0)