Project

General

Profile

Bug #11119

Updated by nobu (Nobuyoshi Nakada) over 9 years ago

MRI lazily determines the name of a class or module by walking all defined constants starting from `Object` Object and looking for the namespace in question. This allows deferring the full name calclation until the class/module is finished being defined. However, if the class or module is *never* accessible via `Object`, Object, then this system-walking occurs for every call to `#name` #name or `#inspect` #inspect on the `class`/`module` class/module and every call to the default `#inspect` #inspect on instances of the class. 

 A simple benchmark: 

 ~~~ruby 
 require 'benchmark' 

 module B 
   module X 
   end 
 end 

 def a 
   c = Class.new 
   c2 = Class.new 
   c.class_eval 'A = c2' 
   c2.class_eval 'A = c' 

   c 
 end 

 c = a 
 x = B::X 

 loop do 
   puts 'named' 
   puts Benchmark.measure { 1_000_000.times { x.name } } 
   puts 'anon' 
   puts Benchmark.measure { 1_000_000.times { c.name } } 
   cobj = c.new 
   puts 'anon obj' 
   puts Benchmark.measure { 1_000_000.times { cobj.inspect } } 
 end 
 ~~~ 
 

 Results on MRI 2.2 and JRuby 1.7 HEAD: 

 MRI: 

 ~~~ 
 named 
   0.210000     0.000000     0.210000 (    0.205585) 
 anon 
  14.170000     0.050000    14.220000 ( 14.259003) 
 anon obj 
  15.750000     0.060000    15.810000 ( 15.864806) 
 ~~~ 
 

 JRuby: 

 ~~~ 
 named 
   0.250000     0.000000     0.250000 (    0.253000) 
 anon 
   0.270000     0.000000     0.270000 (    0.264000) 
 anon obj 
   0.450000     0.000000     0.450000 (    0.447000) 
 ~~~ 
 

 The effect worsens linearly with the size of the system. Running in a freshly-generated Rails app's console: 

 ~~~ 
 named 
   0.260000     0.020000     0.280000 (    0.272182) 
 anon 
 240.900000     0.800000 241.700000 (242.384455) 
 anon obj 
 257.070000     1.110000 258.180000 (261.986562) 
 ~~~ 
 

 I believe MRI needs to give up on looking for the object after the first failed namespace traversal, or else eagerly build this name the way other implementations do (and accept some changes).

Back