aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel
diff options
context:
space:
mode:
authorRyuta Kamizono <kamipo@gmail.com>2019-06-14 08:50:24 +0900
committerRyuta Kamizono <kamipo@gmail.com>2019-06-18 01:03:21 +0900
commitd29d4598972e85df7ee42f5aa969b51d1b14d615 (patch)
tree7358bce0d2680d7f06a07bc04bc59743e4a3643b /activemodel
parentc104bfe424e6cebe9c8e85a38515327a6c88b1f8 (diff)
downloadrails-d29d4598972e85df7ee42f5aa969b51d1b14d615.tar.gz
rails-d29d4598972e85df7ee42f5aa969b51d1b14d615.tar.bz2
rails-d29d4598972e85df7ee42f5aa969b51d1b14d615.zip
Avoid redundant `time.getutc` call if it is already utc time object
Currently `type.serialize` and `connection.{quote|type_cast}` for a time object always does `time.getutc` call regardless of whether it is already utc time object or not, that duplicated proccess (`connection.type_cast(type.serialize(time))`) allocates extra/useless time objects for each type casting. This avoids that redundant `time.getutc` call if it is already utc time object. In the case of a model has timestamps (`created_at` and `updated_at`), it avoids 6,000 time objects allocation for 1,000 times `model.save`. ```ruby ObjectSpace::AllocationTracer.setup(%i{path line type}) pp ObjectSpace::AllocationTracer.trace { 1_000.times { User.create } }.select { |k, _| k[0].end_with?("quoting.rb", "time_value.rb") } ``` Before (c104bfe424e6cebe9c8e85a38515327a6c88b1f8): ``` {["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 203, :T_ARRAY]=>[1004, 0, 778, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 220, :T_STRING]=>[2, 0, 2, 1, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 209, :T_ARRAY]=>[8, 0, 8, 1, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 57, :T_ARRAY]=>[4, 0, 4, 1, 1, 0], ["~/rails/activemodel/lib/active_model/type/helpers/time_value.rb", 17, :T_DATA]=>[4000, 0, 3096, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 120, :T_DATA]=>[2000, 0, 1548, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 126, :T_STRING]=>[4000, 0, 3096, 0, 1, 0]} ``` After (this change): ``` {["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 203, :T_ARRAY]=>[1004, 0, 823, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 220, :T_STRING]=>[2, 0, 2, 1, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 209, :T_ARRAY]=>[8, 0, 8, 1, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 57, :T_ARRAY]=>[4, 0, 4, 1, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 126, :T_STRING]=>[2000, 0, 1638, 0, 1, 0]} ```
Diffstat (limited to 'activemodel')
-rw-r--r--activemodel/lib/active_model/type/helpers/time_value.rb8
-rw-r--r--activemodel/lib/active_model/type/value.rb2
2 files changed, 5 insertions, 5 deletions
diff --git a/activemodel/lib/active_model/type/helpers/time_value.rb b/activemodel/lib/active_model/type/helpers/time_value.rb
index 508fe77531..075e906034 100644
--- a/activemodel/lib/active_model/type/helpers/time_value.rb
+++ b/activemodel/lib/active_model/type/helpers/time_value.rb
@@ -11,10 +11,10 @@ module ActiveModel
value = apply_seconds_precision(value)
if value.acts_like?(:time)
- zone_conversion_method = is_utc? ? :getutc : :getlocal
-
- if value.respond_to?(zone_conversion_method)
- value = value.send(zone_conversion_method)
+ if is_utc?
+ value = value.getutc if value.respond_to?(:getutc) && !value.utc?
+ else
+ value = value.getlocal if value.respond_to?(:getlocal)
end
end
diff --git a/activemodel/lib/active_model/type/value.rb b/activemodel/lib/active_model/type/value.rb
index 994d135b7b..788ded3e96 100644
--- a/activemodel/lib/active_model/type/value.rb
+++ b/activemodel/lib/active_model/type/value.rb
@@ -110,7 +110,7 @@ module ActiveModel
[self.class, precision, scale, limit].hash
end
- def assert_valid_value(*)
+ def assert_valid_value(_)
end
private