1// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package xerrors_test
6
7import (
8	"bytes"
9	"fmt"
10	"math/big"
11	"testing"
12
13	"golang.org/x/xerrors"
14	"golang.org/x/xerrors/internal"
15)
16
17type myType struct{}
18
19func (myType) Format(s fmt.State, v rune) {
20	s.Write(bytes.Repeat([]byte("Hi! "), 10))
21}
22
23func BenchmarkErrorf(b *testing.B) {
24	err := xerrors.New("foo")
25	// pi := big.NewFloat(3.14) // Something expensive.
26	num := big.NewInt(5)
27	args := func(a ...interface{}) []interface{} { return a }
28	benchCases := []struct {
29		name   string
30		format string
31		args   []interface{}
32	}{
33		{"no_format", "msg: %v", args(err)},
34		{"with_format", "failed %d times: %v", args(5, err)},
35		{"method: mytype", "pi: %v", args("myfile.go", myType{}, err)},
36		{"method: number", "pi: %v", args("myfile.go", num, err)},
37	}
38	for _, bc := range benchCases {
39		b.Run(bc.name, func(b *testing.B) {
40			b.Run("ExpWithTrace", func(b *testing.B) {
41				for i := 0; i < b.N; i++ {
42					xerrors.Errorf(bc.format, bc.args...)
43				}
44			})
45			b.Run("ExpNoTrace", func(b *testing.B) {
46				internal.EnableTrace = false
47				defer func() { internal.EnableTrace = true }()
48
49				for i := 0; i < b.N; i++ {
50					xerrors.Errorf(bc.format, bc.args...)
51				}
52			})
53			b.Run("Core", func(b *testing.B) {
54				for i := 0; i < b.N; i++ {
55					fmt.Errorf(bc.format, bc.args...)
56				}
57			})
58		})
59	}
60}
61