Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize Performance with Caching for Resolved Options and Parsed Locale Strings #1642

Merged
merged 4 commits into from
Sep 4, 2024
Merged

Conversation

nodify-at
Copy link
Contributor

@nodify-at nodify-at commented Jun 27, 2024

Changes

  • Caching: Implemented caching to avoid redundant computations of resolved options and locale parsing.
  • Efficient Checks: Introduced a final isEnglish variable to efficiently determine if the locale supports English.
  • Initialization: supportsFastNumbers is now immediately initialized to prevent unnecessary calls.

Performance Impact

Tests indicate up to a 10x speed improvement with these enhancements.

Issue Fixed

Fixes #1428

… 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 <[email protected]>
Copy link

linux-foundation-easycla bot commented Jun 27, 2024

CLA Signed

The committers listed above are authorized under a signed CLA.

@nodify-at nodify-at changed the title Improve Performance by caching resolved options for isEnglish and supportsFastNumbers Optimize Performance with Caching for Resolved Options and Parsed Locale Strings Jun 27, 2024
@nodify-at
Copy link
Contributor Author

Is there any update on this or can someone give me a feedback if I've to improve this PR? :)

@flodlc
Copy link

flodlc commented Jul 5, 2024

Once this one is merged, could we expect a new release ? There has been many perf improvements that would benefits to the community.

@icambron
Copy link
Member

icambron commented Jul 8, 2024

I'll take a look at this one soon

@nodify-at
Copy link
Contributor Author

Thanks @icambron :)

@Seledrex
Copy link

Nice work! I was just investigating this problem myself and stumbled upon this issue. Definitely looking forward to this performance improvement! 🚀

@nodify-at
Copy link
Contributor Author

Hi @icambron,

When would you have time to review this? We're using a temporary patch right now, and it would be great to have this feature in Luxon. This will help us remove the workaround and benefit the community, especially for Node.js apps.

Thanks!

@@ -374,14 +394,14 @@ export default class Locale {
this.eraCache = {};

this.specifiedLocale = specifiedLocale;
this.fastNumbersCached = null;
this.fastNumbersCached = supportsFastNumbers(this);
Copy link
Member

@icambron icambron Aug 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I don't quite know what moving this here is fixing. We may never use fastNumbers(), so I don't love the idea of computing it upfront instead of computing it lazily and only caching it then.

@@ -374,14 +394,14 @@ export default class Locale {
this.eraCache = {};

this.specifiedLocale = specifiedLocale;
this.fastNumbersCached = null;
this.fastNumbersCached = supportsFastNumbers(this);
this.isEnglishCached =
Copy link
Member

@icambron icambron Aug 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, I agree we should cache this, but why not cache it inside isEnglish? That way if isEnglish is never called, we don't pay the performance penalty

}
intlConfigCache[key] = localeStr;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm having a hard time understanding how this would give such a big speedup. Can you use the benchmarks in the repo to demonstrate this?

@@ -73,7 +81,18 @@ function getCachedWeekInfo(locString) {
return data;
}

function parseLocaleString(localeStr) {
const localeStringCache = {};
function getParsedCachedLocaleString(localeStr) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can believe that this parsing is slow, but I'd like to see the benchmarks on this too

Copy link
Member

@icambron icambron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for taking so long to review this. I left some comments

…ers and isEnglish calls to improve performance

Signed-off-by: nodify-at <[email protected]>
@nodify-at
Copy link
Contributor Author

@icambron Thanks for your feedback. I took a thorough approach initially to improve the calls, but I've now simplified it to focus on the isEnglish and fastNumbers calls only. I've also cleaned up all other improvements/changes. Could you please review it again?

@nodify-at
Copy link
Contributor Author

@icambron
I hope I did this correctly. I also added two new benchmark tests to compare the results.

Here are the initial results from my local environment:

DateTime#format in German: 301,824 ops/sec ±0.41% (95 runs sampled)
DateTime#format in German with no-cache: 11,999 ops/sec ±3.03% (88 runs sampled)

@nodify-at
Copy link
Contributor Author

@icambron did you get my last changes ?

@flodlc
Copy link

flodlc commented Aug 27, 2024

I'm starting to lose hope that this PR will ever get merged 😞

@Seledrex
Copy link

I'm starting to lose hope that this PR will ever get merged 😞

Just give it some more time!

@icambron icambron merged commit 3e9983c into moment:master Sep 4, 2024
1 check passed
@icambron
Copy link
Member

icambron commented Sep 4, 2024

Looks good, merged. Thanks for the contribution. I will release this soon.

@nodify-at
Copy link
Contributor Author

Awesome :) Thanks @icambron

@@ -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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be loc.intl?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks a bit strange, because in my last commit I reverted this change. getCachedIntResolvedOptions function is used only in supportsFastNumbers and isEnglish .

See the code in master: https://github.com/moment/luxon/blob/master/src/impl/locale.js

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ops, I see your pointed code better now, sorry and you're right it should be intl.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[perf] isEnglish and supportsFastNumbers are slow - new Intl.DateTimeFormat
5 participants