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