Skip to content

Commit

Permalink
Optimize Backend::Simple#available_locales
Browse files Browse the repository at this point in the history
Previously available_locales was a little bit slow. For each locale in
translations it would:
* build a new array of all the top-level keys in that locale
* build a second array of those keys except :i18n
* add that locale to the list if the second array was not empty

For locales with many translations this can build somewhat sizeable
arrays.

Instead we can perform the same operation, rejecting locales with either
no keys or only :i18n without allocating any new objects. We reject
based on the condition:

    data.size <= 1 && (data.empty? || data.has_key?(:i18n))

This ends up being about 4x faster (though this of course depends on
the exact locales being used):

    Benchmark.ips do |x|
      x.report("I18n.available_locales") do
        I18n.available_locales
      end
    end

Before:

    11.447k (± 2.9%) i/s -     57.869k in   5.059738s

After:

    47.810k (± 2.8%) i/s -    242.060k in   5.067332s
  • Loading branch information
jhawthorn committed Feb 6, 2018
1 parent 7c6ccf4 commit 7eb3576
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion lib/i18n/backend/simple.rb
Expand Up @@ -44,7 +44,7 @@ def store_translations(locale, data, options = {})
def available_locales
init_translations unless initialized?
translations.inject([]) do |locales, (locale, data)|
locales << locale unless (data.keys - [:i18n]).empty?
locales << locale unless data.size <= 1 && (data.empty? || data.has_key?(:i18n))
locales
end
end
Expand Down

0 comments on commit 7eb3576

Please sign in to comment.