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

polyfill: optimize rounding durations to years #1390

Merged
merged 3 commits into from
Mar 2, 2021

Conversation

ryzokuken
Copy link
Member

Rounding durations to years was an operation that was previously of the
order O(Years), since it looped over the number of days. This commit
optimizes that logic by deferring that to calendar-specific PlainDate
arithmetic, essentially making it O(1).

Fixes: #1242

/cc @cjtenny @ptomato @justingrant

@ryzokuken ryzokuken added non-prod-polyfill THIS POLYFILL IS NOT FOR PRODUCTION USE! later-production-polyfill labels Feb 25, 2021
@ryzokuken ryzokuken added this to the Next milestone Feb 25, 2021
@ryzokuken ryzokuken self-assigned this Feb 25, 2021
@codecov
Copy link

codecov bot commented Feb 25, 2021

Codecov Report

Merging #1390 (f1476d4) into main (ca5c22d) will decrease coverage by 46.72%.
The diff coverage is 0.00%.

Impacted file tree graph

@@             Coverage Diff             @@
##             main    #1390       +/-   ##
===========================================
- Coverage   95.73%   49.01%   -46.73%     
===========================================
  Files          19       18        -1     
  Lines       11147     4984     -6163     
  Branches     1806     1089      -717     
===========================================
- Hits        10672     2443     -8229     
- Misses        472     2130     +1658     
- Partials        3      411      +408     
Flag Coverage Δ
test262 49.01% <0.00%> (-0.02%) ⬇️
tests ?

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

Impacted Files Coverage Δ
polyfill/lib/ecmascript.mjs 55.16% <0.00%> (-40.99%) ⬇️
polyfill/lib/calendar.mjs 16.72% <0.00%> (-77.45%) ⬇️
polyfill/lib/zoneddatetime.mjs 42.56% <0.00%> (-55.37%) ⬇️
polyfill/lib/plaindate.mjs 49.38% <0.00%> (-46.66%) ⬇️
polyfill/lib/duration.mjs 53.36% <0.00%> (-44.94%) ⬇️
polyfill/lib/plaintime.mjs 55.12% <0.00%> (-41.50%) ⬇️
polyfill/lib/plaindatetime.mjs 54.31% <0.00%> (-41.20%) ⬇️
polyfill/lib/intl.mjs 65.89% <0.00%> (-34.11%) ⬇️
polyfill/lib/timezone.mjs 63.63% <0.00%> (-30.12%) ⬇️
... and 8 more

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 ca5c22d...f1476d4. Read the comment docs.

Copy link
Collaborator

@ptomato ptomato left a comment

Choose a reason for hiding this comment

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

Thanks! Will look at this in more detail when the spec text change has been added.

polyfill/lib/ecmascript.mjs Outdated Show resolved Hide resolved
Copy link
Collaborator

@cjtenny cjtenny left a comment

Choose a reason for hiding this comment

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

A few nits, but looks good! Flagged two points for either you or @ptomato to update here or in #1393 based on whomever merges first.

polyfill/lib/ecmascript.mjs Outdated Show resolved Hide resolved
@@ -1289,27 +1289,33 @@ <h1>RoundDuration ( _years_, _months_, _weeks_, _days_, _hours_, _minutes_, _sec
1. Let _monthsWeeksInDays_ be ? DaysUntil(_yearsLater_, _yearsMonthsWeeksLater_).
1. Set _relativeTo_ to _yearsLater_.
1. Let _days_ be _days_ + _monthsWeeksInDays_..
1. Let _daysDuration_ be ? CreateTemporalDuration(0, 0, 0, _days_, 0, 0, 0, 0, 0, 0).
1. Let _daysLater_ be ? Call(_dateAdd_, _calendar_, « _relativeTo_, _daysDuration_, _options_, %Temporal.PlainDate% »).
Copy link
Collaborator

Choose a reason for hiding this comment

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

_options_ is currently undefined if _relativeTo_ is undefined, but an empty object otherwise; mind fixing that while you're here for correctness/consistency throughout RoundDuration?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a bug in the spec. The polyfill throws if unit is "years" and there is no calendar (basically no relativeTo). Should I fix it here or in a second PR?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Second PR is fine, thanks!

spec/duration.html Outdated Show resolved Hide resolved
spec/duration.html Outdated Show resolved Hide resolved
spec/duration.html Outdated Show resolved Hide resolved
@ryzokuken ryzokuken force-pushed the duration/roundduration/years branch from 406644d to 643816f Compare March 2, 2021 12:11
1. Let _fractionalYears_ be _years_ + _days_ / abs(_oneYearDays_).
1. Set _years_ to ? RoundNumberToIncrement(_fractionalYears_, _increment_, _roundingMode_).
1. Set _remainder_ to _fractionalYears_ - _years_.
1. Set _months_, _weeks_, and _days_ to 0.
1. Else if _unit_ is *"months"*, then
1. Let _yearsMonths_ be ? CreateTemporalDuration(_years_, _months_, 0, 0, 0, 0, 0, 0, 0, 0).
1. Let _yearsMonthsLater_ be ? Call(_dateAdd_, _calendar_, « _relativeTo_, _yearsMonths_, _options_, %Temporal.PlainDate%).
1. Let _yearsMonthsLater_ be ? Call(_dateAdd_, _calendar_, « _relativeTo_, _yearsMonths_, _options_, %Temporal.PlainDate% »).
Copy link
Collaborator

Choose a reason for hiding this comment

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

This isn't a blocker for this PR, but FYI these should also use CalendarDateAdd but previously didn't because we stored the function in dateAdd so as not to repeatedly observably Get it. This is one mark in favour of the eager-reading proposed in #1294 and I'll fix it up one way or the other when resolving that.

Rounding durations to years was an operation that was previously of the
order O(Years), since it looped over the number of days. This commit
optimizes that logic by deferring that to calendar-specific PlainDate
arithmetic, essentially making it O(1).

Fixes: tc39#1242
Port over polyfill optimizations done against
tc39#1242 to the spec.
@ryzokuken ryzokuken force-pushed the duration/roundduration/years branch from a4ccbc7 to f1476d4 Compare March 2, 2021 19:49
@ptomato ptomato merged commit dccb08f into tc39:main Mar 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
later-production-polyfill non-prod-polyfill THIS POLYFILL IS NOT FOR PRODUCTION USE!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Avoid O(years) loop in RoundDuration
3 participants