From 618bf38c4f2239f29e795247445ac9652aa1a2e3 Mon Sep 17 00:00:00 2001 From: Connor Shea <2977353+connorshea@users.noreply.github.com> Date: Thu, 2 Jul 2026 15:43:30 -0600 Subject: [PATCH] Use memoized I18n.locale_available? in Config.locale I18n.locale_available? checks a memoized set of locales, unlike I18n.available_locales which rebuilds its array on every call, so the common case (the current I18n locale is available) no longer allocates. Benchmark (Ruby 3.4.9, arm64-darwin25, benchmark-ips): require 'benchmark/ips' require 'faker' Benchmark.ips do |x| x.config(warmup: 1, time: 2) x.report('Config.locale') { Faker::Config.locale } end Results: main: Config.locale 178.877k (+/-16.1%) i/s this commit: Config.locale 992.950k (+/- 2.5%) i/s (~5.5x) --- lib/faker.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/faker.rb b/lib/faker.rb index a5d7d472b9..30a87addac 100644 --- a/lib/faker.rb +++ b/lib/faker.rb @@ -24,7 +24,10 @@ def locale=(new_locale) def locale # Because I18n.locale defaults to :en, if we don't have :en in our available_locales, errors will happen - Thread.current[:faker_config_locale] || @default_locale || (I18n.available_locales.include?(I18n.locale) ? I18n.locale : I18n.available_locales.first) + # I18n.locale_available? is used here because it relies on a memoized + # set of locales, unlike I18n.available_locales which is recomputed + # on every call. + Thread.current[:faker_config_locale] || @default_locale || (I18n.locale_available?(I18n.locale) ? I18n.locale : I18n.available_locales.first) end def own_locale