diff options
author | Sam <sam.saffron@gmail.com> | 2014-11-17 14:55:17 +1100 |
---|---|---|
committer | Sam <sam.saffron@gmail.com> | 2014-11-17 14:55:17 +1100 |
commit | da99a2a2982d35f670ad9647463e09bfe9032b70 (patch) | |
tree | e4c452a2fe9d542e2b8e15b41d312f2a0d44531b /activerecord/lib | |
parent | 3a804aab9557efd1f1f3b68a5d1e9e3c2f37df20 (diff) | |
download | rails-da99a2a2982d35f670ad9647463e09bfe9032b70.tar.gz rails-da99a2a2982d35f670ad9647463e09bfe9032b70.tar.bz2 rails-da99a2a2982d35f670ad9647463e09bfe9032b70.zip |
PERF: optimise type lookup to avoid invoking procs
Diffstat (limited to 'activerecord/lib')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb | 20 | ||||
-rw-r--r-- | activerecord/lib/active_record/type/hash_lookup_type_map.rb | 20 |
2 files changed, 32 insertions, 8 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 6310d70192..d3e5b0a4ad 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -431,16 +431,22 @@ module ActiveRecord private def get_oid_type(oid, fmod, column_name, sql_type = '') # :nodoc: - if !type_map.key?(oid) + + result = type_map.fetch(oid, fmod, sql_type) { + nil + } + + unless result load_additional_types(type_map, [oid]) + result = type_map.fetch(oid, fmod, sql_type) { + warn "unknown OID #{oid}: failed to recognize type of '#{column_name}'. It will be treated as String." + Type::Value.new.tap do |cast_type| + type_map.register_type(oid, cast_type) + end + } end - type_map.fetch(oid, fmod, sql_type) { - warn "unknown OID #{oid}: failed to recognize type of '#{column_name}'. It will be treated as String." - Type::Value.new.tap do |cast_type| - type_map.register_type(oid, cast_type) - end - } + result end def initialize_type_map(m) # :nodoc: diff --git a/activerecord/lib/active_record/type/hash_lookup_type_map.rb b/activerecord/lib/active_record/type/hash_lookup_type_map.rb index bf92680268..2a146d38a9 100644 --- a/activerecord/lib/active_record/type/hash_lookup_type_map.rb +++ b/activerecord/lib/active_record/type/hash_lookup_type_map.rb @@ -1,6 +1,12 @@ module ActiveRecord module Type class HashLookupTypeMap < TypeMap # :nodoc: + + def initialize + @cache = {} + super + end + delegate :key?, to: :@mapping def lookup(type, *args) @@ -8,12 +14,24 @@ module ActiveRecord end def fetch(type, *args, &block) - @mapping.fetch(type, block).call(type, *args) + cache = (@cache[type] ||= {}) + resolved = cache[args] + + unless resolved + resolved = cache[args] = @mapping.fetch(type, block).call(type, *args) + end + + resolved end def alias_type(type, alias_type) register_type(type) { |_, *args| lookup(alias_type, *args) } end + + def register_type(key, value=nil, &block) + @cache = {} + super(key, value, &block) + end end end end |