bench_test.go 1.9 KB

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