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

On Sep 30, 4:58 am, Elliot T. [email protected]
wrote:

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