From 7eb3576901317097398ef2e4ccb84238559217b3 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Mon, 5 Feb 2018 16:36:24 -0800 Subject: [PATCH] Optimize Backend::Simple#available_locales MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- lib/i18n/backend/simple.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/i18n/backend/simple.rb b/lib/i18n/backend/simple.rb index ce690484..7c7f4ebb 100644 --- a/lib/i18n/backend/simple.rb +++ b/lib/i18n/backend/simple.rb @@ -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