Boy Maas (m4nic)
┌─posts/2012-06-13-ruby-exceptions-benchmark

Ruby exception handling benchmark

Getting into the nitty gritty details

At work a discussion arised on how fast a ruby exception is. And if it is usable in Rails projects. The discussion started after the conclusion that performance dramatically degraded in a project using the Rails framework.

The question arose how fast ruby handles exceptions. After doing a quick google I could not find an isolated benchmark so I whipped up one myself.

Below the result of the benchmark.

ruby 1.8.7 (2012-02-08 patchlevel 358) [i686-darwin11.2.0]

Rehearsal ----------------------------------------------------
exception          0.770000   0.030000   0.800000 (  0.809420)
exception with e   0.780000   0.040000   0.820000 (  0.814608)
multi exception    0.850000   0.040000   0.890000 (  0.885843)
symbol             0.040000   0.000000   0.040000 (  0.035782)
------------------------------------------- total: 2.550000sec

                       user     system      total        real
exception          0.770000   0.030000   0.800000 (  0.808482)
exception with e   0.780000   0.040000   0.820000 (  0.817195)
multi exception    0.850000   0.040000   0.890000 (  0.889478)
symbol             0.040000   0.000000   0.040000 (  0.036175)

ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin11.2.0]

Rehearsal ----------------------------------------------------
exception          0.890000   0.040000   0.930000 (  0.929162)
exception with e   0.890000   0.030000   0.920000 (  0.934193)
multi exception    0.970000   0.040000   1.010000 (  0.999004)
symbol             0.020000   0.000000   0.020000 (  0.017207)
------------------------------------------- total: 2.880000sec

                       user     system      total        real
exception          0.830000   0.040000   0.870000 (  0.867102)
exception with e   0.830000   0.030000   0.860000 (  0.873007)
multi exception    0.910000   0.040000   0.950000 (  0.938906)
symbol             0.020000   0.000000   0.020000 (  0.017294)

jruby 1.6.7.2 (ruby-1.8.7-p357) (2012-05-01 26e08ba) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_29) [darwin-x86_64-java]

Rehearsal ----------------------------------------------------
exception          8.044000   0.000000   8.044000 (  8.006000)
exception with e   7.704000   0.000000   7.704000 (  7.704000)
multi exception    7.791000   0.000000   7.791000 (  7.791000)
symbol             0.038000   0.000000   0.038000 (  0.038000)
------------------------------------------ total: 23.577000sec

                       user     system      total        real
exception          7.603000   0.000000   7.603000 (  7.603000)
exception with e   7.605000   0.000000   7.605000 (  7.605000)
multi exception    7.529000   0.000000   7.529000 (  7.529000)
symbol             0.009000   0.000000   0.009000 (  0.009000)

The benchmark code

require 'benchmark'

class E1 < StandardError; end
class E2 < StandardError; end
class E3 < StandardError; end

def outer_conditional
  if inner_returns_symbol == :argument_error
    :agument_error
  end
end

def outer_multi_exception
  inner_multi_exception
rescue E1
  :E1
rescue E2
  :E2
rescue E3
  :E3
end

def inner_multi_exception
  raise [E1, E2, E3][rand(3)]
end

def outer_exception
  inner_raises_exception
rescue ArgumentError
  :argument_error
end

def outer_exception_with_e
  inner_raises_exception
rescue ArgumentError => e
  :argument_error
end

def inner_raises_exception
  raise ArgumentError
end

def inner_returns_symbol
  :argument_error
end

COUNT = 100_000

Benchmark.bmbm { |x|
  x.report("exception") do
    COUNT.times { outer_exception }
  end
  x.report("exception with e") do
    COUNT.times { outer_exception_with_e }
  end
  x.report("multi exception") do
    COUNT.times { outer_multi_exception }
  end
  x.report("symbol") do
    COUNT.times { outer_conditional } 
  end
}
j/k scroll h/l prev/next q back gg/G ends s sound