This project is archived and is in readonly mode.
Inflector.constantize uses eval which is slow in JRuby and Ruby 1.9
Reported by enebo | June 13th, 2008 @ 06:25 PM | in 3.0.6
constantize in lib/active_support/inflector.rb uses eval which is slow in both JRuby and Ruby 1.9. This patch passes all tests and also significantly speeds up constantize on these ruby impl (without hurting perf of Ruby 1.8).
Comments and changes to this ticket
-
Chris Lloyd August 7th, 2008 @ 12:24 AM
- Tag set to patch
+1
Passes all tests. I've attached a benchmark which shows this is actually slightly faster with simple constant names running 1.8.6.
It slows down with multiple namespaces. Parity occurs with 3 nested namespaces (A::B::C) but the perf. difference on even up to 7 nested namespaces is minimal. Looks good.
-
Repository August 7th, 2008 @ 01:34 AM
- State changed from new to resolved
(from [88eec8327b179cd41314e85868879b46bcf2530e]) JRuby: improve constantize performance. [#410 state:resolved] http://github.com/rails/rails/co...
-
Repository August 7th, 2008 @ 01:34 AM
(from [ed8a882e47e07b470b71cacd8cd50e251dca4d27]) JRuby: improve constantize performance. [#410 state:resolved] http://github.com/rails/rails/co...
-
Jeremy Kemper August 7th, 2008 @ 01:36 AM
- Assigned user set to Jeremy Kemper
- Tag changed from patch to activesupport, patch
- Milestone set to 2.1.1
-
Michael Johnston September 11th, 2008 @ 08:36 AM
This fails (after about 30 rounds of constantize / const_missing / parent)
@@@ruby class Outer TOM=5 end
module Bob class Mary
class Foo < ::Outer end def self.doit i = ::Bob::Mary::Foo.new puts "dereference: #{::Bob::Mary::Foo::TOM}" puts [constantize: #{](:Bob::Mary::Foo::TOM".constantize}") end
end end
Bob::Mary.doit
for an example in the wild see the init function of picnic
-
Michael Johnston September 11th, 2008 @ 08:37 AM
sigh. lets try that again.
class Outer TOM=5 end module Bob class Mary class Foo < ::Outer end def self.doit i = ::Bob::Mary::Foo.new puts "dereference: #{::Bob::Mary::Foo::TOM}" puts "constantize: #{"::Bob::Mary::Foo::TOM".constantize}" end end end Bob::Mary.doit
for an example in the wild see the init function of picnic
-
Michael Johnston September 11th, 2008 @ 08:51 AM
actually, this fails too:
class Outer2 module Why TOM2 = 5 end include Why end "Outer2::TOM2".constantize
which is why "Logger::INFO".constantize fails which is (another reason) why picnic fails.
-
Jeremy Kemper September 11th, 2008 @ 05:08 PM
- State changed from resolved to open
Michael, could you add a failing test case? Do you have a workaround that doesn't use eval?
-
Jeremy Kemper October 24th, 2008 @ 03:19 AM
- Milestone changed from 2.1.1 to 2.1.3
-
Ripta Pasay December 3rd, 2008 @ 04:46 PM
It's been awhile, so attached is my own attempt a failing test case. I added an "Extension" module to Ace::Base; it's the simplest I could come up with that fails. The "Extension" doesn't break the rest of the test cases.
-
Frederick Cheung December 13th, 2008 @ 06:24 PM
This seems to do the trick, speed seems on par with the previous implementation. Not 100% sure about the ruby 1.9 specific changes, the inflector tests do still pass but I'm not quite up to date on how const_defined? etc.. have changed
-
Frederick Cheung December 14th, 2008 @ 10:08 AM
Oops, ruby 1.9 changes were a bit off. This should be better
-
Repository December 15th, 2008 @ 07:05 PM
- State changed from open to resolved
(from [eca79e6bf052041c018c7ba08750238f8b2ecb7a]) Make constantize look into ancestors
[#410 state:resolved]
Signed-off-by: Jeremy Kemper jeremy@bitsweat.net
Conflicts:
activesupport/lib/active_support/inflector.rb
-
Repository December 15th, 2008 @ 07:05 PM
(from [262fef7ed57520b857605a0105fe7ba9265654f6]) Make constantize look into ancestors
[#410 state:resolved]
Signed-off-by: Jeremy Kemper jeremy@bitsweat.net http://github.com/rails/rails/co...
-
Repository December 15th, 2008 @ 07:05 PM
(from [87790e00ec4a0b24146de3757d1d6892689b05e4]) Make constantize look into ancestors
[#410 state:resolved]
Signed-off-by: Jeremy Kemper jeremy@bitsweat.net http://github.com/rails/rails/co...
-
Repository December 16th, 2008 @ 02:22 AM
- State changed from resolved to open
(from [d7b7ff0556ea5a66aeda455141ba06b558671e3d]) Revert "Make constantize look into ancestors"
[#410 state:open]
This reverts commit 87790e00ec4a0b24146de3757d1d6892689b05e4. http://github.com/rails/rails/co...
-
Repository December 16th, 2008 @ 02:22 AM
(from [981314f45cbb42d1b5403ac0d984f37c82226438]) Revert "Make constantize look into ancestors"
[#410 state:open]
This reverts commit eca79e6bf052041c018c7ba08750238f8b2ecb7a. http://github.com/rails/rails/co...
-
Repository December 16th, 2008 @ 02:22 AM
(from [19be3d35b38b6685789d8d343617d465a3652717]) Revert "Make constantize look into ancestors"
[#410 state:open]
This reverts commit 262fef7ed57520b857605a0105fe7ba9265654f6. http://github.com/rails/rails/co...
-
Matt Jones January 9th, 2009 @ 01:17 AM
- Milestone cleared.
- Tag changed from activesupport, patch to activesupport, bug, patch
What does this patch need to be accepted? It appears from some discussion here and here that the second argument to const_defined? was specifically added to make the test included here pass.
Also ran into this in a Picnic situation; "Logger::DEBUG".constantize wasn't finding the constant.
The 1.9 case in the current code overrides this behavior and restores the (somewhat hard to understand) behavior of Ruby 1.8. I know I was amazed when "Logger::DEBUG".constantize didn't work even though Logger::DEBUG evaluated without error.
-
Yehuda Katz (wycats) January 27th, 2009 @ 05:04 PM
- Milestone cleared.
-
Rohit Arondekar June 17th, 2010 @ 07:31 AM
Any updates in this ticket? is this still a issue on Rails master?
-
Andrew White June 17th, 2010 @ 10:50 AM
The original ticket title no longer applies as eval is no longer used in constantize however Michael Johnston's failing example still fails on master.
The actual problem now is that const_defined? doesn't look for constants in included modules in 1.8.7 but it does in 1.9.x. There's an optional second parameter that turns it off - which is what constantize does. The last patch tries to fix it by searching the ancestors list, however it's probably best to use the optimised behavior on 1.9.x and only search ancestors on 1.8.7.
I can come up with a new patch if you want me to.
-
Rohit Arondekar August 3rd, 2010 @ 07:50 AM
- Importance changed from to Low
Andrew, have you been able to work on that patch?
-
Andrew White August 19th, 2010 @ 06:15 PM
I've looked at it and unfortunately using the optimized const_defined? in 1.9.2 returns top level constants which is different to the required behavior. I looked at using constant.constants.member? but it's unbearably slow. Therefore the technique in Fredrick's patch is about as good as it'll get and it results in about a 33% slowdown for a constant like ActiveSupport::Routing::Mapper. The same is true for 1.8.7 and 1.9.2 and const_defined? is slower by about 33% in 1.9.2 than 1.8.7 anyway.
This may or may not be acceptable - the attached patch is basically an update of Frederick's patch.
-
Santiago Pastorino February 27th, 2011 @ 03:15 AM
- Milestone changed from 3.0.5 to 3.0.6
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>
People watching this ticket
Attachments
Tags
Referenced by
- 410 Inflector.constantize uses eval which is slow in JRuby and Ruby 1.9 (from [88eec8327b179cd41314e85868879b46bcf2530e]) JRuby: ...
- 410 Inflector.constantize uses eval which is slow in JRuby and Ruby 1.9 (from [ed8a882e47e07b470b71cacd8cd50e251dca4d27]) JRuby: ...
- 1020 constantize broken when parent != parent by name see #410 -- I opened a new ticket because I wasn't sure i...
- 410 Inflector.constantize uses eval which is slow in JRuby and Ruby 1.9 [#410 state:resolved]
- 410 Inflector.constantize uses eval which is slow in JRuby and Ruby 1.9 [#410 state:resolved]
- 410 Inflector.constantize uses eval which is slow in JRuby and Ruby 1.9 [#410 state:resolved]
- 410 Inflector.constantize uses eval which is slow in JRuby and Ruby 1.9 [#410 state:open]
- 410 Inflector.constantize uses eval which is slow in JRuby and Ruby 1.9 [#410 state:open]
- 410 Inflector.constantize uses eval which is slow in JRuby and Ruby 1.9 [#410 state:open]