Uh oh!
There was an error while loading. Please reload this page.
errorbase: optimize errors.Is - #153
Conversation
This is a benchmark created by @rafi. It demonstrates `errors.Is` is very inefficient when the reference error does not match the input error.
Previously, `errors.Is` was very inefficient if the reference error did not match any errors in the chain. There were two significant sources of inefficiency: 1. The code would pessimistically construct the error mark for every error in the input error chain. This is O(chain_length^2). This was a lot of unnecessary allocations and caused the runtime to be O(n^2) in the average case instead of O(n). 2. The code compared the `Error()` message before comparing the types. It is possible to compare error types with zero allocations whereas computing the message often requires an allocation.
3ff6ee5 to
3a21e3dCompare| if m1.msg != m2.msg { | ||
| return false | ||
| } | ||
| if len(m1.types) != len(m2.types) { |
There was a problem hiding this comment.
This is a bug that is pretty unlikely to occur in the original implementation that checks error message before types, but its somewhat likely now that we check the types first.
| return true | ||
| } | ||
| for _, reference := range references { | ||
| if Is(err, reference) { |
There was a problem hiding this comment.
I think the reason we didn't use this implementation originally is Is was pretty slow. So it was better to use the quick check before the slow mark check. Now that Is is efficient, we don't need to duplicate the implementations.
There was a problem hiding this comment.
Thanks for the consolidation.
|
dhartunian
left a comment
There was a problem hiding this comment.
@dhartunian reviewed 1 of 3 files at r1, all commit messages.
Reviewable status: 1 of 3 files reviewed, 2 unresolved discussions (waiting on @jeffswenson)
| return true | ||
| } | ||
| for _, reference := range references { | ||
| if Is(err, reference) { |
There was a problem hiding this comment.
Thanks for the consolidation.
jeffswenson
commented
Oct 10, 2025
Thanks for the review! |
Uh oh!
There was an error while loading. Please reload this page.
155254: go.mod: update cockroachdb/errors package r=jeffswenson a=jeffswenson Update the errors package to get the performance optimization from cockroachdb/errors#153. Release note: none Informs: #154125 Co-authored-by: Jeff Swenson <jeffswenson@betterthannull.com>
benchmark: add a benchmark for the errors package
This is a benchmark created by @rafiss. It demonstrates
errors.Isis very inefficient when the reference error does not match the
input error.
errbase: optimize errors.Is
Previously,
errors.Iswas very inefficient if the reference error didnot match any errors in the chain.
There were two significant sources of inefficiency:
error in the input error chain. This is O(chain_length^2). This was
a lot of unnecessary allocations and caused the runtime to be O(n^2)
in the average case instead of O(n).
Error()message before comparing the types.It is possible to compare error types with zero allocations whereas
computing the message often requires an allocation.
refs: cockroachdb/cockroach#154555
This change is