diff options
author | Andrey Chernih <andrey.chernih@gmail.com> | 2014-05-25 12:55:29 +0400 |
---|---|---|
committer | Andrey Chernih <andrey.chernih@gmail.com> | 2014-05-27 17:38:34 +0400 |
commit | 3a0888203031b91a583f8ce35763f8d231467827 (patch) | |
tree | 22bfcabd391b00d95d03a9be6b327b02d7b0f351 /activesupport | |
parent | f632f79b8dcd144408c66a544984b2ba9cf52f87 (diff) | |
download | rails-3a0888203031b91a583f8ce35763f8d231467827.tar.gz rails-3a0888203031b91a583f8ce35763f8d231467827.tar.bz2 rails-3a0888203031b91a583f8ce35763f8d231467827.zip |
Speed-up TimeWithZone to String conversion
I've noticed that `String(model.created_at)` is performing poorly in comparision
with other fields. The source of the problem is a way `Kernel#String` works: it first
tries to call `to_str` (which causes `NoMethodError` in `method_missing`) and then calls `to_s`.
Performance tests:
tz = Time.zone.now
Benchmark.ips do |x|
x.report { String(tz) }
end
Without this code:
Calculating -------------------------------------
572 i/100ms
-------------------------------------------------
10177.7 (±18.2%) i/s - 48620 in 5.000325s
With this code:
Calculating -------------------------------------
1518 i/100ms
-------------------------------------------------
138984.2 (±10.1%) i/s - 677028 in 4.974897s
Diffstat (limited to 'activesupport')
-rw-r--r-- | activesupport/lib/active_support/time_with_zone.rb | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb index f2a2f3c3db..3155c0ab0f 100644 --- a/activesupport/lib/active_support/time_with_zone.rb +++ b/activesupport/lib/active_support/time_with_zone.rb @@ -353,6 +353,14 @@ module ActiveSupport initialize(variables[0].utc, ::Time.find_zone(variables[1]), variables[2].utc) end + # respond_to_missing? is not called in some cases, such as when type conversion is + # performed with Kernel#String + def respond_to?(sym, include_priv = false) + # ensure that we're not going to throw and rescue from NoMethodError in method_missing which is slow + return false if sym.to_sym == :to_str + super + end + # Ensure proxy class responds to all methods that underlying time instance # responds to. def respond_to_missing?(sym, include_priv) |