Module#name very slow for anonymous modules

Notice it gets much worse with rails loaded. Anyone got a fix, or know why this is happening?

cg5[20:55] development > ruby -v ruby 1.8.6 (2008-03-03 patchlevel 114) [universal-darwin9.0] cg5[20:51] development > irb irb(main):001:0> require 'benchmark' => true irb(main):002:0> n = 5000 => 5000 irb(main):003:0> m1 = Module.new => #<Module:0x5d6c54> irb(main):004:0> module M2; end => nil irb(main):005:0> Benchmark.bm do |x| irb(main):006:1* x.report { n.times do m1.name end } irb(main):007:1> x.report { n.times do M2.name end } irb(main):008:1> end       user system total real   1.710000 0.050000 1.760000 ( 2.807539)   0.010000 0.000000 0.010000 ( 0.005157) => true irb(main):009:0> ^Dcg5[20:51] development > script/console Loading development environment (Rails 2.0.2)

require 'benchmark'

=>

n = 5000

=> 5000

m1 = Module.new

=> #<Module:0x205c308>

module M2; end

=> nil

Benchmark.bm do |x|

?> x.report { n.times do m1.name end }

  x.report { n.times do M2.name end } end

      user system total real 14.120000 0.630000 14.750000 ( 28.017196)   0.000000 0.000000 0.000000 ( 0.010137) => true

Looks like the code changed in edge rails, but as a temporary patch do this one line change in environment.rb which avoids calling Module#name if there is no name:

module ActionView   module Helpers     module PrototypeHelper       class JavaScriptGenerator         def include_helpers_from_context           @context.extended_by.each do |mod|             extend mod unless defined?(mod) == 'constant' && mod.name =~ /^ActionView::Helpers/           end           extend GeneratorMethods         end       end     end   end end

Notice it gets much worse with rails loaded. Anyone got a fix, or know why this is happening?

I don't think it is Rails' fault (at least not directly). I ran the test you ran and got:

      user system total real   0.710000 0.010000 0.720000 ( 0.715909)   0.010000 0.000000 0.010000 ( 0.013030)

Then I ran 'Aaaa'.upto('Azzz') { |x| Object.const_set(x, '1'), ie I generated 20000 or so extra constants and reran the benchmarks and got

22.300000 0.250000 22.550000 ( 23.584470)   0.000000 0.000000 0.000000 ( 0.005260)

Adding the same number of constants again doubles those numbers - it would appear that there is something in ruby that makes Module#name linear in the number of constants set in the case where the name is unset So I don't think Rails is doing anything that makes this worse, other than defining a whole bunch of constants

Fred