i18n
i18n copied to clipboard
I18n.localize ignores cache for time objects
When localizing times in an "most recently updated" index list then those Time
objects obviously change all the time.
the .localize
method passes in the object in question to the options of the translate method despite only looking for the format string for strftime
.
Which means this gets passed through to any caching layer and since options are part of the cache key it prevents caching of such highly volatile values.
Running the index page through a profiler repeatedly yields this result, which is about 10% of the overall runtime:
| # Acts the same as +strftime+, but uses a localized version of the
| # format string. Takes a key from the date/time formats translations as
| # a format argument (<em>e.g.</em>, <tt>:short</tt> in <tt>:'date.formats'</tt>).
| def localize(locale, object, format = :default, options = {})
35.5ms | raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime)
|
3.8ms | if Symbol === format
| key = format
23.5ms | type = object.respond_to?(:sec) ? 'time' : 'date'
108.8ms | options = options.merge(:raise => true, :object => object, :locale => locale)
9663.2ms | format = I18n.t(:"#{type}.formats.#{key}", options)
| end
|
| # format = resolve(locale, object, format, options)
32.7ms | format = format.to_s.gsub(/%[aAbBp]/) do |match|
| case match
| when '%a' then I18n.t(:"date.abbr_day_names", :locale => locale, :format => format)[object.wday]
| when '%A' then I18n.t(:"date.day_names", :locale => locale, :format => format)[object.wday]
| when '%b' then I18n.t(:"date.abbr_month_names", :locale => locale, :format => format)[object.mon]
| when '%B' then I18n.t(:"date.month_names", :locale => locale, :format => format)[object.mon]
| when '%p' then I18n.t(:"time.#{object.hour < 12 ? :am : :pm}", :locale => locale, :format => format) if object.respond_to? :hour
| end
| end
|
1031.5ms | object.strftime(format)
| end
My workaround is to monkeypatch the cache backend to strip the :object key from the options if its value is a time-like object.
Good point where I18n
could be optimized.
twitter/twitter-cldr-rb
(https://github.com/twitter/twitter-cldr-rb) has some pretty advanced localization code already, based on the Unicode CLDR library. Perhaps some collaboration/sharing with that project would be good.
(not immediately related to this performance issue, but if we could avoid duplication across that project and this one it could be a good thing)