From 0640c6d963fbf368ed6309a8585802b45ecee146 Mon Sep 17 00:00:00 2001 From: Oliver Kriska Date: Tue, 16 Jun 2026 10:25:41 +0200 Subject: [PATCH] Compute plural info once per PO file at compile time `compile_po_file/5` derived the plural data twice: once in `nplurals/3` and once in `compile_plural_forms/4`, each calling `Plural.plural_info/3`. That function runs `Code.ensure_compiled!/1` and parses the `Plural-Forms` header, so it is needless work repeated for every PO file across all locales and domains. Compute `plural_info` once in `compile_po_file/5` and pass it to both helpers. The generated code is identical (the same value is escaped into the plural dispatcher and fed to `nplurals/1`); only the duplicate computation is removed. --- CHANGELOG.md | 1 + lib/gettext/compiler.ex | 16 +++++++--------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a82f28d..d6f5c94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased + * Call `c:Gettext.Plural.init/1` once per PO file at compile time instead of twice. * Reduce the compile time of backends that use the default interpolation module by storing translations without interpolation in a literal map instead of generating one function clause each. * Add experimental `mix gettext.generate` task: messages are persisted as module attributes during normal compilation (for backends with `automatic_extraction: true` in the application environment, for example `config :gettext, MyApp.Gettext, automatic_extraction: true` in `config/dev.exs`) and read back from the compiled BEAM files, so extraction no longer needs to force-recompile the project. diff --git a/lib/gettext/compiler.ex b/lib/gettext/compiler.ex index 5a0575b..00db60d 100644 --- a/lib/gettext/compiler.ex +++ b/lib/gettext/compiler.ex @@ -498,8 +498,9 @@ defmodule Gettext.Compiler do plural_forms_fun = :"#{locale}_#{domain}_plural" - plural_forms = compile_plural_forms(locale, messages_struct, plural_mod, plural_forms_fun) - nplurals = nplurals(locale, messages_struct, plural_mod) + plural_info = Plural.plural_info(locale, messages_struct, plural_mod) + plural_forms = compile_plural_forms(plural_info, plural_mod, plural_forms_fun) + nplurals = nplurals(plural_info, plural_mod) singular_fun = :"#{locale}_#{domain}_lgettext" plural_fun = :"#{locale}_#{domain}_lngettext" @@ -608,17 +609,14 @@ defmodule Gettext.Compiler do end end - defp nplurals(locale, messages_struct, plural_mod) do - plural_mod.nplurals(Plural.plural_info(locale, messages_struct, plural_mod)) + defp nplurals(plural_info, plural_mod) do + plural_mod.nplurals(plural_info) end - defp compile_plural_forms(locale, messages_struct, plural_mod, plural_fun) do + defp compile_plural_forms(plural_info, plural_mod, plural_fun) do quote do defp unquote(plural_fun)(n) do - unquote(plural_mod).plural( - unquote(Macro.escape(Plural.plural_info(locale, messages_struct, plural_mod))), - n - ) + unquote(plural_mod).plural(unquote(Macro.escape(plural_info)), n) end end end