Created
April 26, 2010 19:29
-
-
Save JangoSteve/379771 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
# Created by Steve Schwartz [1] (for Alfa Jango [2]) with the help of David Leal [3] | |
# [1] http://github.com/jangosteve | |
# [2] http://www.alfajango.com | |
# [3] http://github.com/david | |
# The latest version of this script may be found at http://gist.github.com/371710 | |
require 'benchmark' | |
class OptionsHashBenchmarker | |
# assume an options hash of options => {:this => {:that => 'other'}} | |
# and we want to do some operation if options[:this][:that] is defined and true | |
VALID_OPTIONS = {:this => {:that => 'other'}} | |
OTHER_OPTIONS = {:nothing => 'stuff'} | |
def self.rescue_method(options={}) | |
begin | |
if options[:this][:that] | |
#p "rescue_method doing stuff" | |
end | |
rescue | |
ensure | |
#p "rescue_method doing more stuff" | |
end | |
end | |
def self.chained_tries(options={}) | |
if options.try(:[], :this).try(:[], :that) | |
#p "chained_tries doing stuff" | |
end | |
#p "chained_tries doing more stuff" | |
end | |
def self.chained_if(options={}) | |
if options && options[:this] && options[:this][:that] | |
#p "chained_if doing stuff" | |
end | |
#p "chained_if doing more stuff" | |
end | |
def self.hash_extension(options={}) | |
if options.deep_fetch(:this, :that) | |
#p "hash_extension doing stuff" | |
end | |
#p "hash_extension doing other stuff" | |
end | |
def self.nil_extension(options={}) | |
if options[:this][:that] | |
#p "nil_extension doing stuff" | |
end | |
#p "nil_extension doing more stuff" | |
end | |
def self.test_normal | |
Hash.class_eval do | |
def deep_fetch(*keys) | |
keys.inject(self) { |h, k| if h then h[k] else return h end } | |
end | |
end | |
n=1000000 | |
Benchmark.bm do |x| | |
x.report("rescue_method (valid):") { n.times do ; rescue_method(VALID_OPTIONS); end } | |
x.report("chained_tries (valid):") { n.times do ; chained_tries(VALID_OPTIONS); end } | |
x.report("chained_if (valid):") { n.times do ; chained_if(VALID_OPTIONS); end } | |
x.report("hash_extension (valid):") { n.times do ; hash_extension(VALID_OPTIONS); end } | |
x.report("rescue_method (other):") { n.times do ; rescue_method(OTHER_OPTIONS); end } | |
x.report("chained_tries (other):") { n.times do ; chained_tries(OTHER_OPTIONS); end } | |
x.report("chained_if (other):") { n.times do ; chained_if(OTHER_OPTIONS); end } | |
x.report("hash_extension (other):") { n.times do ; hash_extension(OTHER_OPTIONS); end } | |
x.report("rescue_method (none):") { n.times do ; rescue_method; end } | |
x.report("chained_tries (none):") { n.times do ; chained_tries; end } | |
x.report("chained_if (none):") { n.times do ; chained_if; end } | |
x.report("hash_extension (none):") { n.times do ; hash_extension; end } | |
end | |
end | |
# nil_extension must be put into its own method, so that NilClass doesn't get extended for the rescue_method (which would then never call the rescue block since it would no longer generate an exception) | |
def self.test_nil_extension | |
NilClass.class_eval do | |
def [](key) | |
nil | |
end | |
end | |
n=1000000 | |
Benchmark.bm do |x| | |
x.report("nil_extension (valid):") { n.times do ; nil_extension(VALID_OPTIONS); end } | |
x.report("nil_extension (other):") { n.times do ; nil_extension(OTHER_OPTIONS); end } | |
x.report("nil_extension (none):") { n.times do ; nil_extension; end } | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Run again on Ruby 1.8, this time with new Hash#deep_find extension:
rescue_method (valid): 0.700000 0.010000 0.710000 ( 0.708726)
chained_tries (valid): 0.800000 0.000000 0.800000 ( 0.823636)
chained_if (valid): 0.800000 0.010000 0.810000 ( 0.844903)
nil_extension (valid): 0.600000 0.000000 0.600000 ( 0.611619)
hash_extension (valid): 3.060000 0.020000 3.080000 ( 3.153540)
rescue_method (other): 37.810000 1.420000 39.230000 ( 40.710294)
chained_tries (other): 1.230000 0.010000 1.240000 ( 1.268215)
chained_if (other): 0.650000 0.000000 0.650000 ( 0.680624)
nil_extension (other): 0.840000 0.000000 0.840000 ( 0.863451)
hash_extension (other): 3.500000 0.020000 3.520000 ( 3.548087)
rescue_method (none): 38.070000 1.410000 39.480000 ( 40.272977)
chained_tries (none): 2.080000 0.010000 2.090000 ( 2.120892)
chained_if (none): 1.410000 0.010000 1.420000 ( 1.417036)
nil_extension (none): 1.610000 0.010000 1.620000 ( 1.637559)
hash_extension (none): 4.310000 0.010000 4.320000 ( 4.503614)