diff options
author | Sean Griffin <sean@thoughtbot.com> | 2014-11-18 15:27:42 -0800 |
---|---|---|
committer | Sean Griffin <sean@thoughtbot.com> | 2014-11-18 15:27:42 -0800 |
commit | a04851702b0e8e694a92139c3ee9f3b1622f3f5d (patch) | |
tree | 9e93f878b2d6cdd96dea4665e14510665ee41218 /lib | |
parent | 590c784a30b13153667f8db7915998d7731e24e5 (diff) | |
download | rails-a04851702b0e8e694a92139c3ee9f3b1622f3f5d.tar.gz rails-a04851702b0e8e694a92139c3ee9f3b1622f3f5d.tar.bz2 rails-a04851702b0e8e694a92139c3ee9f3b1622f3f5d.zip |
Use class objects rather than strings for the dispatch cache
The only reason we're using strings is to pre-populate the cache, but
`Class#name` returns a new string instance on every call. This is a
pretty major source of memory usage. We don't technically need to
pre-populate the cache, and not doing so allows us to go back to using
cache objects
Diffstat (limited to 'lib')
-rw-r--r-- | lib/arel/visitors/reduce.rb | 8 | ||||
-rw-r--r-- | lib/arel/visitors/visitor.rb | 20 |
2 files changed, 10 insertions, 18 deletions
diff --git a/lib/arel/visitors/reduce.rb b/lib/arel/visitors/reduce.rb index 1d74934fe5..9670cad27c 100644 --- a/lib/arel/visitors/reduce.rb +++ b/lib/arel/visitors/reduce.rb @@ -10,14 +10,14 @@ module Arel private def visit object, collector - send dispatch[object.class.name], object, collector + send dispatch[object.class], object, collector rescue NoMethodError => e - raise e if respond_to?(dispatch[object.class.name], true) + raise e if respond_to?(dispatch[object.class], true) superklass = object.class.ancestors.find { |klass| - respond_to?(dispatch[klass.name], true) + respond_to?(dispatch[klass], true) } raise(TypeError, "Cannot visit #{object.class}") unless superklass - dispatch[object.class.name] = dispatch[superklass.name] + dispatch[object.class] = dispatch[superklass] retry end end diff --git a/lib/arel/visitors/visitor.rb b/lib/arel/visitors/visitor.rb index 2152da9f05..bfe7342f04 100644 --- a/lib/arel/visitors/visitor.rb +++ b/lib/arel/visitors/visitor.rb @@ -12,17 +12,9 @@ module Arel private def self.dispatch_cache - dispatch = Hash.new do |hash, class_name| - hash[class_name] = "visit_#{(class_name || '').gsub('::', '_')}" + Hash.new do |hash, klass| + hash[klass] = "visit_#{(klass.name || '').gsub('::', '_')}" end - - # pre-populate cache. FIXME: this should be passed in to each - # instance, but we can do that later. - self.class.private_instance_methods.sort.each do |name| - next unless name =~ /^visit_(.*)$/ - dispatch[$1.gsub('_', '::')] = name - end - dispatch end def get_dispatch_cache @@ -34,14 +26,14 @@ module Arel end def visit object - send dispatch[object.class.name], object + send dispatch[object.class], object rescue NoMethodError => e - raise e if respond_to?(dispatch[object.class.name], true) + raise e if respond_to?(dispatch[object.class], true) superklass = object.class.ancestors.find { |klass| - respond_to?(dispatch[klass.name], true) + respond_to?(dispatch[klass], true) } raise(TypeError, "Cannot visit #{object.class}") unless superklass - dispatch[object.class.name] = dispatch[superklass.name] + dispatch[object.class] = dispatch[superklass] retry end end |