mirror of https://github.com/gin-gonic/gin.git
improve sliceValidateError.Error performance using switch and strings.Builder (#2765)
fix missing nil pointer check use simpler switch case add missing tests use for-loop instead of range add benchmark test codes
This commit is contained in:
parent
1d0f938f28
commit
e3ee01d185
|
@ -20,15 +20,27 @@ type defaultValidator struct {
|
|||
|
||||
type sliceValidateError []error
|
||||
|
||||
// Error concatenates all error elements in sliceValidateError into a single string separated by \n.
|
||||
func (err sliceValidateError) Error() string {
|
||||
var errMsgs []string
|
||||
for i, e := range err {
|
||||
if e == nil {
|
||||
continue
|
||||
n := len(err)
|
||||
switch n {
|
||||
case 0:
|
||||
return ""
|
||||
default:
|
||||
var b strings.Builder
|
||||
if err[0] != nil {
|
||||
fmt.Fprintf(&b, "[%d]: %s", 0, err[0].Error())
|
||||
}
|
||||
errMsgs = append(errMsgs, fmt.Sprintf("[%d]: %s", i, e.Error()))
|
||||
if n > 1 {
|
||||
for i := 1; i < n; i++ {
|
||||
if err[i] != nil {
|
||||
b.WriteString("\n")
|
||||
fmt.Fprintf(&b, "[%d]: %s", i, err[i].Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
return strings.Join(errMsgs, "\n")
|
||||
}
|
||||
|
||||
var _ StructValidator = &defaultValidator{}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package binding
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkSliceValidateError(b *testing.B) {
|
||||
const size int = 100
|
||||
for i := 0; i < b.N; i++ {
|
||||
e := make(sliceValidateError, size)
|
||||
for j := 0; j < size; j++ {
|
||||
e[j] = errors.New(strconv.Itoa(j))
|
||||
}
|
||||
if len(e.Error()) == 0 {
|
||||
b.Errorf("error")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,26 @@ func TestSliceValidateError(t *testing.T) {
|
|||
want string
|
||||
}{
|
||||
{"has nil elements", sliceValidateError{errors.New("test error"), nil}, "[0]: test error"},
|
||||
{"has zero elements", sliceValidateError{}, ""},
|
||||
{"has one element", sliceValidateError{errors.New("test one error")}, "[0]: test one error"},
|
||||
{"has two elements",
|
||||
sliceValidateError{
|
||||
errors.New("first error"),
|
||||
errors.New("second error"),
|
||||
},
|
||||
"[0]: first error\n[1]: second error",
|
||||
},
|
||||
{"has many elements",
|
||||
sliceValidateError{
|
||||
errors.New("first error"),
|
||||
errors.New("second error"),
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
errors.New("last error"),
|
||||
},
|
||||
"[0]: first error\n[1]: second error\n[5]: last error",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue