aboutsummaryrefslogtreecommitdiffstats
path: root/lib/arel
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2014-11-18 15:27:42 -0800
committerSean Griffin <sean@thoughtbot.com>2014-11-18 15:27:42 -0800
commita04851702b0e8e694a92139c3ee9f3b1622f3f5d (patch)
tree9e93f878b2d6cdd96dea4665e14510665ee41218 /lib/arel
parent590c784a30b13153667f8db7915998d7731e24e5 (diff)
downloadrails-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/arel')
-rw-r--r--lib/arel/visitors/reduce.rb8
-rw-r--r--lib/arel/visitors/visitor.rb20
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