Основная нагрузка в Intl API возникает не на этапе форматирования, а
при создании экземпляров объектов. Конструкторы
Intl.DateTimeFormat, Intl.NumberFormat,
Intl.Collator выполняют значительную работу при
инициализации:
Именно этот этап делает создание форматтера сравнительно дорогой операцией.
const formatter = new Intl.NumberFormat("ru-RU", {
style: "currency",
currency: "RUB"
});
Вызов конструктора включает подготовку всей локали, и при массовом создании объектов затраты становятся заметными.
После создания экземпляра основная операция — вызов методов форматирования — значительно дешевле:
format() у Intl.NumberFormat работает за
близкое к O(1) времяformat() у Intl.DateTimeFormat
оптимизирован под повторное использование внутренних структурcompare() у Intl.Collator использует
предвычисленные правила сравненияformatter.format(123456.78);
Здесь отсутствует повторная инициализация локали, поэтому вызовы масштабируются линейно по количеству операций, но с минимальным коэффициентом.
Критическое различие в производительности проявляется при следующих подходах:
function formatPrice(value) {
return new Intl.NumberFormat("ru-RU", {
style: "currency",
currency: "RUB"
}).format(value);
}
Здесь при каждом вызове функции создаётся новый экземпляр, что приводит к:
const formatter = new Intl.NumberFormat("ru-RU", {
style: "currency",
currency: "RUB"
});
function formatPrice(value) {
return formatter.format(value);
}
Повторное использование экземпляра исключает стоимость повторной инициализации.
Intl.DateTimeFormat обладает более высокой внутренней
сложностью по сравнению с числовым форматированием:
const dtf = new Intl.DateTimeFormat("ru-RU", {
year: "numeric",
month: "long",
day: "numeric"
});
dtf.format(Date.now());
Форматирование даты включает больше вычислений, чем чисел, особенно при частой смене временных зон.
Intl.Collator используется для локализованного сравнения
строк и сортировки:
const collator = new Intl.Collator("ru-RU");
collator.compare("яблоко", "язык");
Сравнение строк зависит от:
Хотя compare() быстрый, его стоимость выше обычного
localeCompare без параметров только при некорректном
использовании (создание нового коллатора на каждое сравнение).
Intl API рассчитан на повторное использование экземпляров. Кэширование снижает стоимость практически до нуля относительно инициализации.
Типовые стратегии:
Разные локали могут иметь различную сложность обработки:
en-US) обрабатываются
быстрееОсобенно заметно это при первом создании экземпляра, когда происходит загрузка данных ICU.
Производительность Intl зависит от движка:
Различия проявляются в:
Основные источники аллокаций:
Intl.*Частое создание форматтеров приводит к:
Измерение производительности Intl требует учёта:
Типичная ошибка — измерение только format() без учёта
конструктора, что даёт искажённую картину.
Некоторые опции увеличивают нагрузку:
style: "unit" и сложные единицы измеренияnotation: "compact" с локализацией сокращенийtimeZone в DateTimeFormatsensitivity в CollatorЧем сложнее конфигурация, тем выше цена инициализации.
На уровне архитектуры производительность зависит от следующих факторов:
Примитивные решения без Intl:
Intl API:
В циклах с миллионами итераций ключевым фактором становится не форматирование, а наличие или отсутствие повторного создания объектов:
for (let i = 0; i < 1e6; i++) {
formatter.format(i);
}
Такой подход остаётся быстрым при условии заранее созданного
formatter.
Создание внутри цикла приводит к экспоненциальному росту затрат времени.
Производительность Intl API можно разложить на три уровня: