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

Speed up non-ISO calendar tests about 10x by caching DateTimeFormat instances #1624

Merged
merged 2 commits into from
Jul 9, 2021

Conversation

justingrant
Copy link
Collaborator

@justingrant justingrant commented Jul 9, 2021

I was wrong about what was making non-ISO calendars so slow. I thought the problem was formatToParts(), but it turns out that the DateTimeFormat constructor is really slow and also allocates ridiculous amounts of RAM. See more details here: https://bugs.chromium.org/p/v8/issues/detail?id=6528

@littledan in https://bugs.chromium.org/p/v8/issues/detail?id=6528#c4 recommended to cache DateTimeFormat instances, so that's what this commit does.

The result is about a 6x 10x speedup in non-ISO calendar tests.

  • Before: 6398.83ms
  • After: 1062.26ms 626.64ms (UPDATE: final code is even faster)

I also added proper caching of global builtins like other Temporal code uses.

Many thanks to @fer22f for uncovering this optimization (and its root cause) in js-temporal/temporal-polyfill#7. As he notes in that issue, a similar speedup is likely for ES.GetCanonicalTimeZoneIdentifier. Caching time zone canonicalization (in a separate PR) should have a big positive impact on ZonedDateTIme and TimeZone perf.

@codecov
Copy link

codecov bot commented Jul 9, 2021

Codecov Report

Merging #1624 (1b805d8) into main (986ae00) will increase coverage by 0.00%.
The diff coverage is 100.00%.

❗ Current head 1b805d8 differs from pull request most recent head a012b4f. Consider uploading reports for the commit a012b4f to get more accurate results
Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1624   +/-   ##
=======================================
  Coverage   91.04%   91.04%           
=======================================
  Files          17       17           
  Lines       10705    10714    +9     
  Branches     1600     1601    +1     
=======================================
+ Hits         9746     9755    +9     
  Misses        943      943           
  Partials       16       16           
Flag Coverage Δ
tests 90.09% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
polyfill/lib/calendar.mjs 91.40% <100.00%> (+0.03%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 986ae00...a012b4f. Read the comment docs.

@justingrant justingrant changed the title Speed up non-ISO calendar tests about 6x by caching DateTimeFormat instances Speed up non-ISO calendar tests about 10x by caching DateTimeFormat instances Jul 9, 2021
justingrant added a commit to justingrant/temporal-polyfill that referenced this pull request Jul 9, 2021
Copy link
Collaborator

@Ms2ger Ms2ger left a comment

Choose a reason for hiding this comment

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

All good, but can you split into two commits - one with the caching of builtin methods, and one with the getFormatter changes?

Add proper caching of global builtins like other Temporal code uses.
I was wrong about what was making non-ISO calendars so slow. I
thought the problem was `formatToParts()`, but it turns out that the
`DateTimeFormat` constructor is really slow and also allocates
ridiculous amounts of RAM. See more details here:
https://bugs.chromium.org/p/v8/issues/detail?id=6528

@littledan in https://bugs.chromium.org/p/v8/issues/detail?id=6528#c4
recommended to cache DateTimeFormat instances, so that's what this
commit does.

The result is a 6x speedup in non-ISO calendar tests.
Before: 6398.83ms
After: 1062.26ms

A similar speedup is likely for `ES.GetCanonicalTimeZoneIdentifier`.
Caching time zone canonicalization (in a separate PR) should have
a big positive impact on ZonedDateTIme and TimeZone perf.

Many thanks to @fer22f for uncovering this optimization in
js-temporal/temporal-polyfill#7.
@ptomato
Copy link
Collaborator

ptomato commented Jul 9, 2021

I've split it up into two commits.

ptomato pushed a commit to justingrant/temporal-polyfill that referenced this pull request Jul 9, 2021
ptomato pushed a commit to js-temporal/temporal-polyfill that referenced this pull request Jul 9, 2021
@ptomato
Copy link
Collaborator

ptomato commented Jul 9, 2021

I guess this meets the bar for what we should port over from the new polyfill, if it speeds up the tests so significantly. It's not important for this part of the code to keep matching the spec (because there is no part of the spec for it to match - the non-ISO calendars are implementation-defined.)

@ptomato ptomato merged commit 44995c7 into tc39:main Jul 9, 2021
@justingrant justingrant mentioned this pull request Jul 10, 2021
@justingrant justingrant added the non-prod-polyfill THIS POLYFILL IS NOT FOR PRODUCTION USE! label Jul 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
non-prod-polyfill THIS POLYFILL IS NOT FOR PRODUCTION USE!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants