We're working on something new! Hook Relay gives you Stripe-quality webhooks in minutes. Sign up for free today! Check out Hook Relay

Benchmarking exceptions in Ruby - yep, they're slow.

Just how much slower are exceptions than other flow control mechanisms? In this post we use a simple benchmark to find out.

I've always strongly suspected that exceptions would be slow in ruby compared to other flow control mechanisms. After all - exceptions are a heck of a lot more complicated than a simple "break" or "return." But I've been wrong in my hunches before, so I thought I'd put it to the test.

In the code below I'm using the benchmark-ips gem to compare the relative performance of exiting a loop via exception, break and return. I've seen examples on the web of people doing benchmarks like this with mri 1.9. But I wanted to try it out with mri 2.2.

require 'benchmark/ips'

def exit_via_exception
  5.times do 
    raise RuntimeError

def exit_via_break
  5.times do 

def exit_via_return
  5.times do 

Benchmark.ips do |x|
  x.report("exception") {  exit_via_exception }
  x.report("break") {  exit_via_break }
  x.report("return") {  exit_via_return }

The results are pretty staggering. The function using the exception is less than half as fast as those using break and return.

$ ruby exception_benchmark.rb
Calculating -------------------------------------
           exception    50.872k i/100ms
               break   125.322k i/100ms
              return   124.173k i/100ms
           exception    714.795k (± 2.7%) i/s -      3.612M
               break      3.459M (± 3.1%) i/s -     17.294M
              return      3.379M (± 3.0%) i/s -     16.888M

This isn't a perfect benchmark

There are a couple of issues that I'm not sure how to compensate for. For example, the exception and break methods have to return. So they're doing more than the method which simply returns. Also I'd be interested to see if rescuing the exception adds to the performance overhead. But not rescuing it causes the benchmark to abort.

Still, exception is so much slower than the other examples that I think the results have meaning even if they're not perfect.

The lesson we learned?

If you're using exceptions as a flow control mechanism. Stop now! Especially if you have a loop consisting of exceptions being raised and caught over and over.

Will this change how I personally use exceptions? Probably not. I can live with a little slowness if the slowness is an exception to the rule. :)

...But what about JRuby and RBx?

Josh Cheek (@josh_cheek on twitter) wrote his own version of this benchmark which is more comprehensive then mine. And he ran it against multiple ruby implementations. You can see his results here. Apparently break is still the winner. :)

Honeybadger has your back when it counts. We're the only error tracker that combines exception monitoring, uptime monitoring, and cron monitoring into a single, simple to use platform.

Our mission: to tame production and make you a better, more productive developer. Learn more

author photo

Starr Horne

Starr Horne is a Rubyist and Chief JavaScripter at Honeybadger.io. When she's not neck-deep in other people's bugs, she enjoys making furniture with traditional hand-tools, reading history and brewing beer in her garage in Seattle.

“We’ve looked at a lot of error management systems. Honeybadger is head and shoulders above the rest and somehow gets better with every new release.”
Michael Smith
Try Error Monitoring Free for 15 Days