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

replace O(n^2) LOC with constant-prop in Dates #46036

Merged
merged 6 commits into from
Aug 20, 2022

Conversation

LilithHafner
Copy link
Member

julia> using Dates, Base.Order

julia> @code_llvm lt(By(Dates.days  oneunit, Reverse), Week(3), Quarter(2))
;  @ ordering.jl:119 within `lt`
define i8 @julia_lt_9867([1 x i64]* nocapture noundef nonnull readonly align 8 dereferenceable(8) %0, [1 x i64]* nocapture noundef nonnull readonly align 8 dereferenceable(8) %1) #0 {
top:
  ret i8 0
}

@LilithHafner LilithHafner added the dates Dates, times, and the Dates stdlib module label Jul 14, 2022
@@ -170,7 +131,7 @@ struct CompoundPeriod <: AbstractTime
function CompoundPeriod(p::Vector{Period})
n = length(p)
if n > 1
sort!(p, rev=true, lt=periodisless)
sort!(p, rev = true, by = days ∘ oneunit)
Copy link
Member

Choose a reason for hiding this comment

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

Hmmm, what's going on here? Can you explain the magic?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure!

We sort periods in decreasing order (rev = true) according to the length of the period (e.g Week(1) before Hour(240)). There are many ways to get the length of a period p and days(oneunit(p)) seems like a reasonable choice. How many days is one Second/Week/Year? This is sometimes a Flaot64 and sometimes an Int64 but we already don't have type stability because we are working with Vector{Period} and this constant folds once the type is known.

Copy link
Member Author

Choose a reason for hiding this comment

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

That explanation feels a bit long to include as a comment, but we could if you think it is appropriate.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah adding a comment on how this works is probably a good idea, specially given that the code it replaces is pretty obvious in how it works

Copy link
Member Author

Choose a reason for hiding this comment

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

Does this explain it adequitely?

# We sort periods in decreasing order (rev = true) according to the length of
# the period's type (by = days ∘ oneunit). We sort by type, not value, so that
# we can merge equal types.
#
# This works by computing how many days are in a single period, and then sorting
# by that. For example, (days ∘ oneunit)(Week(10)) = days(oneunit(Week(10))) =
# days(Week(1)) = 7, which is less than (days ∘ oneunit)(Month(-2)) = 30.436875

Copy link
Member Author

Choose a reason for hiding this comment

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

Even if this is less obvious, I think its a worthwhile change because it takes the number of new methods to be implemented for a new Period type to support CompundPeriods down from O(n) to 0.

Copy link
Member

Choose a reason for hiding this comment

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

That sounds quite clear 👍

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks!

Lilith Hafner and others added 5 commits July 14, 2022 10:20
To distinguish small period types from each other. 
This avoids JuliaLang#46150 and, more importantly, fixes:

```julia
julia> Dates.days(Millisecond(1))
0

julia> Dates.days(Second(1))
0
```
@KristofferC KristofferC added the merge me PR is reviewed. Merge when all tests are passing label Aug 19, 2022
@N5N3 N5N3 merged commit 079ed73 into JuliaLang:master Aug 20, 2022
@N5N3 N5N3 removed the merge me PR is reviewed. Merge when all tests are passing label Aug 20, 2022
@LilithHafner LilithHafner deleted the cleanup-dates-1 branch August 20, 2022 17:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dates Dates, times, and the Dates stdlib module
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants