From: Charles Nutter Date: 2011-06-23T07:34:40+09:00 Subject: [ruby-core:37301] [Ruby 1.9 - Feature #4917] NilClass#to_ary Issue #4917 has been updated by Charles Nutter. Perhaps if an optimization is needed, it could just be adding a nil check to Kernel#Array. ---------------------------------------- Feature #4917: NilClass#to_ary http://redmine.ruby-lang.org/issues/4917 Author: Jay Feldblum Status: Rejected Priority: Normal Assignee: Category: Target version: As a performance improvement in certain cases, nil should respond to to_ary. Kernel#Array, when passed nil, first tries to send to_ary to nil (which actually ends up calling method_missing on nil) and then tries to send to_a to nil which finally succeeds. When Kernel#Array is used often, for example in library/gem code, this can have a noticeable, if relatively small, negative impact on the overall application performance. $ irb > RUBY_VERSION => "1.9.2" > require 'benchmark' > def bench(times) Benchmark.bmbm{|x| x.report{times.times(&Proc.new)}} end # Let's zero the scale.... > bench(10_000_000) { } # The "before" benchmark.... > bench(10_000_000) { Array(nil) } # An optimization.... > NilClass.class_eval { alias to_ary to_a } # The "after" benchmark.... > bench(10_000_000) { Array(nil) } # Much faster! # Let's see how many times method_missing actually gets called.... > NilClass.class_eval { undef to_ary } > class NilClass > alias method_missing_without_hit method_missing > def method_missing(name, *args, &block) > $method_missing_hits += 1 > method_missing_without_hit(name, *args, &block) > end > end > $method_missing_hits = 0 > bench(100_000) { Array(nil) } # Very slow! > $method_missing_hits => 200005 > NilClass.class_eval { alias to_ary to_a } > $method_missing_hits = 0 > bench(100_000) { Array(nil) } # Instantaneous! > $method_missing_hits => 0 -- http://redmine.ruby-lang.org