From 80bff42fdd0380c09f4df35c4baacb9cfdae5aae Mon Sep 17 00:00:00 2001 From: dmathieu <42@dmathieu.com> Date: Wed, 11 Dec 2024 09:55:27 +0000 Subject: [PATCH] errors: optimize errors.Join for single unwrappable errors Change-Id: I10bbb782ca7234cda8c82353f2255eec5be588c9 GitHub-Last-Rev: e5ad8fdb802e56bb36c41b4982ed27c1e0809af8 GitHub-Pull-Request: golang/go#70770 Reviewed-on: https://go-review.googlesource.com/c/go/+/635115 Auto-Submit: Sean Liao Reviewed-by: Michael Pratt Reviewed-by: Sean Liao Reviewed-by: Dmitri Shuralyov LUCI-TryBot-Result: Go LUCI --- src/errors/join.go | 12 ++++++++++++ src/errors/join_test.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/errors/join.go b/src/errors/join.go index 349fc06ed9..dd50089c29 100644 --- a/src/errors/join.go +++ b/src/errors/join.go @@ -26,6 +26,18 @@ func Join(errs ...error) error { if n == 0 { return nil } + if n == 1 { + for _, err := range errs { + if err != nil { + if _, ok := err.(interface { + Unwrap() []error + }); ok { + return err + } + } + } + } + e := &joinError{ errs: make([]error, 0, n), } diff --git a/src/errors/join_test.go b/src/errors/join_test.go index 4828dc4d75..439b372ca0 100644 --- a/src/errors/join_test.go +++ b/src/errors/join_test.go @@ -70,3 +70,37 @@ func TestJoinErrorMethod(t *testing.T) { } } } + +func BenchmarkJoin(b *testing.B) { + for _, bb := range []struct { + name string + errs []error + }{ + { + name: "no error", + }, + { + name: "single non-nil error", + errs: []error{errors.New("err")}, + }, + { + name: "multiple errors", + errs: []error{errors.New("err"), errors.New("newerr"), errors.New("newerr2")}, + }, + { + name: "unwrappable single error", + errs: []error{errors.Join(errors.New("err"))}, + }, + { + name: "nil first error", + errs: []error{nil, errors.New("newerr")}, + }, + } { + b.Run(bb.name, func(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + _ = errors.Join(bb.errs...) + } + }) + } +}