public
Created

respond_to_vs_include.rb - Fancy benchmark: who is faster? is respond_to? or include?

  • Download Gist
respond_to_vs_include.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
# Fancy benchmark...
# is respond_to? so faster than include?
 
require 'benchmark'
 
n = 10_000_000
mock_methods = ('a'..'z').to_a
 
class Mock
end
 
mock_methods.each do |m|
Mock.class_eval do
send(:attr_accessor, m)
end
end
 
mock = Mock.new
instance_meths = Mock.instance_methods(false)
 
Benchmark.bm(15) do |test|
test.report('respond_to?: ') do
n.times do
mock.respond_to? :k
end
end
test.report('include?: ') do
n.times do
instance_meths.include? :k
end
end
end
 
__END__
 
-- results: --
user system total real
respond_to?: 2.340000 0.000000 2.340000 ( 2.344671)
include?: 17.180000 0.000000 17.180000 ( 17.192215)

I created a fork which shows that include? isn't constant time and actually depends on instance_meths.size. Output is in that fork, but here's a summary:

                      user     system      total        real
respond_to?(a)    0.030000   0.000000   0.030000 (  0.031189)
respond_to?(b)    0.030000   0.000000   0.030000 (  0.031101)
respond_to?(c)    0.030000   0.000000   0.030000 (  0.031507)
[...]
respond_to?(x)    0.030000   0.000000   0.030000 (  0.029806)
respond_to?(y)    0.030000   0.000000   0.030000 (  0.030761)
respond_to?(z)    0.030000   0.000000   0.030000 (  0.029590)
include?(a)       0.020000   0.000000   0.020000 (  0.023256)
include?(b)       0.050000   0.000000   0.050000 (  0.050267)
include?(c)       0.070000   0.000000   0.070000 (  0.070923)
[...]
include?(x)       0.540000   0.000000   0.540000 (  0.534326)
include?(y)       0.550000   0.000000   0.550000 (  0.558297)
include?(z)       0.560000   0.000000   0.560000 (  0.569605)

As the code runs you'll see it spends longer and longer trying to find later elements of instance_meths as it searches through the contents of the array.

Interesting @aprescott... Thank you!

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.