From 3e9983cd0680fdf7836fcee638d34e3edc682380 Mon Sep 17 00:00:00 2001 From: Hasan Ozdemir <21654050+nodify-at@users.noreply.github.com> Date: Wed, 4 Sep 2024 03:57:08 +0200 Subject: [PATCH] Optimize Performance with Caching for Resolved Options and Parsed Locale Strings (#1642) * feat: optimize performance by adding caching for resolved options and parsed locale strings - Implement caching to avoid redundant computations of resolved options and locale parsing. - Introduce a final `isEnglish` variable to efficiently check if the locale supports English. Signed-off-by: nodify-at <21654050+nodify-at@users.noreply.github.com> * feat: simplify caching logic for resolved options in supportsFastNumbers and isEnglish calls to improve performance Signed-off-by: nodify-at <21654050+nodify-at@users.noreply.github.com> * feat: add new benchmark tests to compare performance with and without Intl.resolvedOptions cache Signed-off-by: nodify-at <21654050+nodify-at@users.noreply.github.com> --------- Signed-off-by: nodify-at <21654050+nodify-at@users.noreply.github.com> --- benchmarks/datetime.js | 7 +++++++ src/impl/locale.js | 14 +++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/benchmarks/datetime.js b/benchmarks/datetime.js index f4dffda7b..aef549810 100644 --- a/benchmarks/datetime.js +++ b/benchmarks/datetime.js @@ -58,6 +58,13 @@ function runDateTimeSuite() { dt.toFormat("T"); Settings.resetCaches(); }) + .add("DateTime#format in german", () => { + dt.setLocale("de-De").toFormat("d. LLL. HH:mm"); + }) + .add("DateTime#format in german and no-cache", () => { + dt.setLocale("de-De").toFormat("d. LLL. HH:mm"); + Settings.resetCaches(); + }) .add("DateTime#add", () => { dt.plus({ milliseconds: 3434 }); }) diff --git a/src/impl/locale.js b/src/impl/locale.js index 93c489b07..b0ecc8c08 100644 --- a/src/impl/locale.js +++ b/src/impl/locale.js @@ -61,6 +61,14 @@ function systemLocale() { } } +let intlResolvedOptionsCache = {}; +function getCachedIntResolvedOptions(locString) { + if (!intlResolvedOptionsCache[locString]) { + intlResolvedOptionsCache[locString] = new Intl.DateTimeFormat(locString).resolvedOptions(); + } + return intlResolvedOptionsCache[locString]; +} + let weekInfoCache = {}; function getCachedWeekInfo(locString) { let data = weekInfoCache[locString]; @@ -167,7 +175,7 @@ function supportsFastNumbers(loc) { loc.numberingSystem === "latn" || !loc.locale || loc.locale.startsWith("en") || - new Intl.DateTimeFormat(loc.intl).resolvedOptions().numberingSystem === "latn" + getCachedIntResolvedOptions(loc.locale).numberingSystem === "latn" ); } } @@ -326,7 +334,6 @@ const fallbackWeekSettings = { /** * @private */ - export default class Locale { static fromOpts(opts) { return Locale.create( @@ -353,6 +360,7 @@ export default class Locale { intlDTCache = {}; intlNumCache = {}; intlRelCache = {}; + intlResolvedOptionsCache = {}; } static fromObject({ locale, numberingSystem, outputCalendar, weekSettings } = {}) { @@ -506,7 +514,7 @@ export default class Locale { return ( this.locale === "en" || this.locale.toLowerCase() === "en-us" || - new Intl.DateTimeFormat(this.intl).resolvedOptions().locale.startsWith("en-us") + getCachedIntResolvedOptions(this.intl).locale.startsWith("en-us") ); }