mirror of https://github.com/rails/rails
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 (c104bfe424
):
```
{["~/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]}
```
This commit is contained in:
parent
c104bfe424
commit
d29d459897
|
@ -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
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ module ActiveModel
|
|||
[self.class, precision, scale, limit].hash
|
||||
end
|
||||
|
||||
def assert_valid_value(*)
|
||||
def assert_valid_value(_)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -114,16 +114,16 @@ module ActiveRecord
|
|||
# if the value is a Time responding to usec.
|
||||
def quoted_date(value)
|
||||
if value.acts_like?(:time)
|
||||
zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
|
||||
|
||||
if value.respond_to?(zone_conversion_method)
|
||||
value = value.send(zone_conversion_method)
|
||||
if ActiveRecord::Base.default_timezone == :utc
|
||||
value = value.getutc if value.respond_to?(:getutc) && !value.utc?
|
||||
else
|
||||
value = value.getlocal if value.respond_to?(:getlocal)
|
||||
end
|
||||
end
|
||||
|
||||
result = value.to_s(:db)
|
||||
if value.respond_to?(:usec) && value.usec > 0
|
||||
"#{result}.#{sprintf("%06d", value.usec)}"
|
||||
result << "." << sprintf("%06d", value.usec)
|
||||
else
|
||||
result
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue