Last active
December 14, 2022 22:39
-
-
Save shasderias/a94689999ce350c8963607f5cb43b44a to your computer and use it in GitHub Desktop.
Go Error Checking Performance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package errorperf | |
import ( | |
"errors" | |
"fmt" | |
"math/rand" | |
"os" | |
"strconv" | |
) | |
var ErrInvalidInput = InvalidInputError{val: 1} | |
type InvalidInputError struct { | |
val int | |
} | |
func (e InvalidInputError) Error() string { | |
return fmt.Sprintf("%d", e.val) | |
} | |
func (e InvalidInputError) MyError() int { | |
return e.val | |
} | |
type MyError interface { | |
error | |
MyError() int | |
} | |
var nMax int | |
func init() { | |
var err error | |
nMax, err = strconv.Atoi(os.Getenv("N_MAX")) | |
if err != nil { | |
panic(err) | |
} | |
} | |
func ErrReturningFunc() error { | |
n := rand.Intn(nMax) | |
switch { | |
case n < 5: | |
return fmt.Errorf("error: %w", fmt.Errorf("error: %w", fmt.Errorf("error: %w", ErrInvalidInput))) | |
case n < 10: | |
return fmt.Errorf("error: %w", fmt.Errorf("error: %w", ErrInvalidInput)) | |
case n < 15: | |
return fmt.Errorf("error: %w", ErrInvalidInput) | |
case n < 50: | |
return ErrInvalidInput | |
default: | |
return nil | |
} | |
} | |
func ErrCheckingFunc_Sentinel() int { | |
if err := ErrReturningFunc(); err != nil { | |
if err == ErrInvalidInput { | |
return 1 | |
} | |
return 2 | |
} | |
return 0 | |
} | |
func ErrCheckingFunc_Assertion() int { | |
if err := ErrReturningFunc(); err != nil { | |
if _, ok := err.(InvalidInputError); ok { | |
return 1 | |
} | |
return 2 | |
} | |
return 0 | |
} | |
func ErrCheckingFunc_Is() int { | |
if err := ErrReturningFunc(); err != nil { | |
if errors.Is(ErrReturningFunc(), ErrInvalidInput) { | |
return 1 | |
} | |
return 2 | |
} | |
return 0 | |
} | |
func ErrCheckingFunc_As_Interface() int { | |
if err := ErrReturningFunc(); err != nil { | |
var myError MyError | |
if errors.As(ErrReturningFunc(), &myError) { | |
return 1 | |
} | |
return 2 | |
} | |
return 0 | |
} | |
func ErrCheckingFunc_As_Concrete() int { | |
if err := ErrReturningFunc(); err != nil { | |
var invalInputErr InvalidInputError | |
if errors.As(ErrReturningFunc(), &invalInputErr) { | |
return 1 | |
} | |
return 2 | |
} | |
return 0 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package errorperf | |
import "testing" | |
func BenchmarkErrCheckingFunc_Sentinel(b *testing.B) { | |
for i := 0; i < b.N; i++ { | |
ErrCheckingFunc_Sentinel() | |
} | |
} | |
func BenchmarkErrCheckingFunc_Assertion(b *testing.B) { | |
for i := 0; i < b.N; i++ { | |
ErrCheckingFunc_Assertion() | |
} | |
} | |
func BenchmarkErrCheckingFunc_Is(b *testing.B) { | |
for i := 0; i < b.N; i++ { | |
ErrCheckingFunc_Is() | |
} | |
} | |
func BenchmarkErrCheckingFunc_As_Concrete(b *testing.B) { | |
for i := 0; i < b.N; i++ { | |
ErrCheckingFunc_As_Concrete() | |
} | |
} | |
func BenchmarkErrCheckingFunc_As_Interface(b *testing.B) { | |
for i := 0; i < b.N; i++ { | |
ErrCheckingFunc_As_Interface() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
C:\dev\sandbox\errorperf>set N_MAX=100 | |
C:\dev\sandbox\errorperf>go test -bench . | |
goos: windows | |
goarch: amd64 | |
pkg: sandbox/errorperf | |
cpu: AMD Ryzen 9 3900X 12-Core Processor | |
BenchmarkErrCheckingFunc_Sentinel-24 12766431 92.51 ns/op | |
BenchmarkErrCheckingFunc_Assertion-24 12698238 94.82 ns/op | |
BenchmarkErrCheckingFunc_Is-24 8108030 149.0 ns/op | |
BenchmarkErrCheckingFunc_As_Concrete-24 6106879 193.0 ns/op | |
BenchmarkErrCheckingFunc_As_Interface-24 5393304 220.1 ns/op | |
PASS | |
ok sandbox/errorperf 6.919s | |
C:\dev\sandbox\errorperf>set N_MAX=1000 | |
C:\dev\sandbox\errorperf>go test -bench . | |
goos: windows | |
goarch: amd64 | |
pkg: sandbox/errorperf | |
cpu: AMD Ryzen 9 3900X 12-Core Processor | |
BenchmarkErrCheckingFunc_Sentinel-24 55815250 20.25 ns/op | |
BenchmarkErrCheckingFunc_Assertion-24 60001500 20.36 ns/op | |
BenchmarkErrCheckingFunc_Is-24 53334518 22.46 ns/op | |
BenchmarkErrCheckingFunc_As_Concrete-24 46156686 25.67 ns/op | |
BenchmarkErrCheckingFunc_As_Interface-24 47059191 24.39 ns/op | |
PASS | |
ok sandbox/errorperf 6.211s | |
C:\dev\sandbox\errorperf> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment