Created
December 5, 2018 10:21
-
-
Save fnordfish/a8733c8aed8efea05934aaffc853601c to your computer and use it in GitHub Desktop.
Micro-benchmarking different error handling methods in ruby
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
# frozen_string_literal: true | |
# Some, probable not extreamly clever, micro benchmarks to compare | |
# different methods of "return a value or error". | |
# The samples benchmark the error path only. | |
require 'benchmark/ips' | |
require 'dry/monads/result' | |
M = Dry::Monads | |
Result = Struct.new(:success, :value) | |
def _return_nil; nil end | |
def _return_failure; M.Failure("error") end | |
def _return_struct; Result.new(false, "error") end | |
def _raise_error; raise StandardError, "error" end | |
def _throw_error; throw(:test, "error") end | |
def fastest | |
result = _return_nil | |
result if result | |
end | |
def medium | |
result = catch(:test) { _throw_error } | |
result | |
end | |
def slow | |
result = begin | |
_raise_error | |
rescue StandardError => e | |
nil | |
end | |
result | |
end | |
def dry_failure | |
result = _return_failure | |
result.value_or(nil) | |
end | |
def result_struct | |
result = _return_struct | |
result.success ? result.value : nil | |
end | |
Benchmark.ips do |x| | |
x.warmup = 100 | |
x.report('return') { fastest } | |
x.report('throw') { medium } | |
x.report('raise') { slow } | |
x.report('Failure()') { dry_failure } | |
x.report('Struct') { result_struct } | |
x.compare! | |
end | |
### | |
# macOS 10.14.1 | |
# Intel(R) Core(TM) i7-4980HQ CPU @ 2.80GHz | |
# 16GB RAM | |
# Lots of background noise | |
### | |
# | |
# ruby 2.6.0preview3 (2018-11-06 trunk 65578) [x86_64-darwin18] | |
# raise_vs_return.rb:28: warning: assigned but unused variable - e | |
# Calculating ------------------------------------- | |
# return 207.114k i/100ms | |
# throw 143.958k i/100ms | |
# raise 74.611k i/100ms | |
# Failure() 38.082k i/100ms | |
# Struct 149.491k i/100ms | |
# ------------------------------------------------- | |
# return 14.433M (± 4.2%) i/s - 72.076M | |
# throw 3.772M (± 3.1%) i/s - 18.858M | |
# raise 1.121M (± 4.7%) i/s - 5.596M | |
# Failure() 472.264k (± 3.4%) i/s - 2.361M | |
# Struct 4.539M (± 3.2%) i/s - 22.723M | |
# | |
# Comparison: | |
# return: 14433477.6 i/s | |
# Struct: 4538907.4 i/s - 3.18x slower | |
# throw: 3771951.7 i/s - 3.83x slower | |
# raise: 1120595.5 i/s - 12.88x slower | |
# Failure(): 472264.2 i/s - 30.56x slower | |
# | |
### | |
# | |
# ruby --jit -v raise_vs_return.rb | |
# ruby 2.6.0preview3 (2018-11-06 trunk 65578) +JIT [x86_64-darwin18] | |
# raise_vs_return.rb:28: warning: assigned but unused variable - e | |
# Calculating ------------------------------------- | |
# return 224.228k i/100ms | |
# throw 148.997k i/100ms | |
# raise 75.438k i/100ms | |
# Failure() 38.648k i/100ms | |
# Struct 164.680k i/100ms | |
# ------------------------------------------------- | |
# return 24.915M (± 4.6%) i/s - 124.222M | |
# throw 3.983M (± 6.3%) i/s - 19.817M | |
# raise 1.139M (± 3.0%) i/s - 5.733M | |
# Failure() 485.783k (± 6.4%) i/s - 2.435M | |
# Struct 5.195M (± 6.0%) i/s - 25.855M | |
# | |
# Comparison: | |
# return: 24914915.7 i/s | |
# Struct: 5194806.9 i/s - 4.80x slower | |
# throw: 3982539.1 i/s - 6.26x slower | |
# raise: 1139278.3 i/s - 21.87x slower | |
# Failure(): 485783.5 i/s - 51.29x slower | |
# | |
### | |
# | |
# jruby 9.2.4.1 (2.5.0) 2018-11-28 f487d1e Java HotSpot(TM) 64-Bit Server VM 25.60-b23 on 1.8.0_60-b27 +jit [darwin-x86_64] | |
# Calculating ------------------------------------- | |
# return 148.276k i/100ms | |
# throw 52.078k i/100ms | |
# raise 1.389k i/100ms | |
# Failure() 1.294k i/100ms | |
# Struct 113.227k i/100ms | |
# ------------------------------------------------- | |
# return 18.470M (± 7.6%) i/s - 91.486M | |
# throw 917.148k (± 2.9%) i/s - 4.583M | |
# raise 14.407k (± 3.6%) i/s - 72.228k | |
# Failure() 13.793k (± 2.1%) i/s - 69.876k | |
# Struct 6.767M (± 4.0%) i/s - 33.742M | |
# | |
# Comparison: | |
# return: 18469948.6 i/s | |
# Struct: 6767455.3 i/s - 2.73x slower | |
# throw: 917147.5 i/s - 20.14x slower | |
# raise: 14407.3 i/s - 1281.99x slower | |
# Failure(): 13793.2 i/s - 1339.06x slower# |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment