Skip to content

Instantly share code, notes, and snippets.

@silent-e
Last active May 13, 2023 04:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save silent-e/714a44e04bd3958ac44ba77d610e9baf to your computer and use it in GitHub Desktop.
Save silent-e/714a44e04bd3958ac44ba77d610e9baf to your computer and use it in GitHub Desktop.
Catch throw vs raise rescue vs baseline return but with unique lambda variable names (Ruby v3.2.2)
require 'benchmark/ips'
Benchmark.ips do |x|
code1 = -> { catch(:foo) { throw(:foo, 'catch/throw') } }
x.report("catch a throw") {
value = code1.call
}
code2 = -> { begin; raise RuntimeError; rescue RuntimeError; 'raise/rescue' end }
x.report("rescue and exception") {
value = code2.call
}
empty_backtrace = []
code3 = -> { begin; raise RuntimeError, '', empty_backtrace; rescue RuntimeError; 'raise/rescue empty backtrace' end }
x.report('Rescue no backtrace') {
value = code3.call
}
code4 = -> { 'string' }
x.report("return string") {
value = code4.call
}
x.compare!
end
# Warming up --------------------------------------
# catch a throw 311.884k i/100ms
# rescue and exception 103.576k i/100ms
# Rescue no backtrace 169.104k i/100ms
# return string 1.000M i/100ms
# Calculating -------------------------------------
# catch a throw 3.221M (± 2.9%) i/s - 16.218M in 5.039158s
# rescue and exception 1.026M (± 2.9%) i/s - 5.179M in 5.052430s
# Rescue no backtrace 1.643M (± 4.3%) i/s - 8.286M in 5.051742s
# return string 10.117M (± 2.8%) i/s - 51.024M in 5.047568s
# Comparison:
# return string: 10116850.1 i/s
# catch a throw: 3221372.1 i/s - 3.14x slower
# Rescue no backtrace: 1643378.7 i/s - 6.16x slower
# rescue and exception: 1025930.8 i/s - 9.86x slower
@silent-e
Copy link
Author

updated by adding the empty backtrace option based on this stack overflow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment