-
Notifications
You must be signed in to change notification settings - Fork 194
Performance improvements for Calendar.RecurrenceRule
#981
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
Conversation
Sources/FoundationEssentials/Calendar/Calendar_Recurrence.swift
Outdated
Show resolved
Hide resolved
Sources/FoundationEssentials/Calendar/Calendar_Recurrence.swift
Outdated
Show resolved
Hide resolved
Sources/FoundationEssentials/Calendar/Calendar_Recurrence.swift
Outdated
Show resolved
Hide resolved
Sources/FoundationEssentials/Calendar/Calendar_Recurrence.swift
Outdated
Show resolved
Hide resolved
Sources/FoundationEssentials/Calendar/Calendar_Recurrence.swift
Outdated
Show resolved
Hide resolved
The benchmark improvements are exciting |
Sources/FoundationEssentials/Calendar/Calendar_Recurrence.swift
Outdated
Show resolved
Hide resolved
@swift-ci please test |
4bf3d71
to
afc2c56
Compare
@swift-ci please test |
@@ -54,7 +54,7 @@ let benchmarks = { | |||
} | |||
|
|||
// Only available in Swift 6 for non-Darwin platforms, macOS 15 for Darwin | |||
#if swift(>=6.0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need Swift 6 mode to run the benchmarks, just a Swift 6 compiler
@@ -511,14 +512,8 @@ extension Calendar { | |||
matchingPolicy: MatchingPolicy, | |||
repeatedTimePolicy: RepeatedTimePolicy, | |||
direction: SearchDirection, | |||
inSearchingDate: Date, | |||
inSearchingDate searchingDate: Date, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function gets split into two, with the latter _adjustDates
being exposed for recurrence enumeration.
@@ -1393,7 +1405,7 @@ extension Calendar { | |||
} | |||
} | |||
|
|||
private func dateAfterMatchingEra(startingAt startDate: Date, components: DateComponents, direction: SearchDirection, matchedEra: inout Bool) -> Date? { | |||
internal func dateAfterMatchingEra(startingAt startDate: Date, components: DateComponents, direction: SearchDirection, matchedEra: inout Bool) -> Date? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some dateAfterMatching*
functions are exposed for recurrence enumeration as well.
We also need the perf results for the other calendar enumeration tests, to make sure those haven't regressed. |
The original implementation of `Calendar.RecurrenceRule` expanded recurrences of dates using the Calendar APIs for matching date components. This would result in multiple sequences for matching date components even when just a single sequence would have sufficed, thus requiring more time and memory to complete enumeration E.g: finding the dates for Thanksgivings (fourth Thursday of each November) took ~4 times as much time using RecurrenceRule when compared to simply matching date components. This commit optimizes how we expand dates for recurrences. Instead of creating a sequence for each value of each component in the recurrence rule, we introduce a new type of sequence closely resembling Calendar.DatesByMatching, but which also allows multiple values per date component.
I just reran all of the Calendar benchmarks, results below. There are a few small regressions that seem to be due to measuring tolerances, e.g. Benchmark baseline comparison
|
71ff275
to
084549f
Compare
@swift-ci please run |
@swift-ci please test |
1 similar comment
@swift-ci please test |
The original implementation of `Calendar.RecurrenceRule` expanded recurrences of dates using the Calendar APIs for matching date components. This would result in multiple sequences for matching date components even when just a single sequence would have sufficed, thus requiring more time and memory to complete enumeration E.g: finding the dates for Thanksgivings (fourth Thursday of each November) took ~4 times as much time using RecurrenceRule when compared to simply matching date components. This commit optimizes how we expand dates for recurrences. Instead of creating a sequence for each value of each component in the recurrence rule, we introduce a new type of sequence closely resembling Calendar.DatesByMatching, but which also allows multiple values per date component.
The original implementation of
Calendar.RecurrenceRule
expanded recurrences ofdates using the Calendar APIs for matching date components. This would result in
multiple sequences for matching date components even when just a single sequence
would have sufficed, thus requiring more time and memory to complete enumeration
E.g: finding the dates for Thanksgivings (fourth Thursday of each November) took
~4 times as much time using RecurrenceRule when compared to simply matching date
components.
This commit optimizes how we expand dates for recurrences. Instead of creating a
sequence for each value of each component in the recurrence rule, we introduce a
new type of sequence closely resembling Calendar.DatesByMatching, but which also
allows multiple values per date component.
Addresses #555
Preliminary benchmarks