-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Fix length(::AbstractUnitRange)
and speed up length(::AbstractUnitRange{<:Rational})
#41479
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
Changes from all commits
6fd2576
206f154
c8e04d6
4a49d28
6a4a9a8
0078f1e
7110222
926029d
c39e26b
875a0fa
e6528e1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -533,3 +533,21 @@ function hash(x::Rational{<:BitInteger64}, h::UInt) | |||||||
h = hash_integer(num, h) | ||||||||
return h | ||||||||
end | ||||||||
|
||||||||
# These methods are only needed for performance. Since `first(r)` and `last(r)` have the | ||||||||
# same denominator (because their difference is an integer), `length(r)` can be calulated | ||||||||
# without calling `gcd`. | ||||||||
function length(r::AbstractUnitRange{T}) where T<:Rational | ||||||||
sostock marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method not only adds performance but changes behavior as well: Without this method, I realize that we are okay with an overflowing I will add a specialized There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is okay, since it should generally only overflow for extreme values that are unlikely |
||||||||
@_inline_meta | ||||||||
f = first(r) | ||||||||
l = last(r) | ||||||||
return div(l.num - f.num + f.den, f.den) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
This change would reduce the risk of overflow, but would be slightly less performant (two integer divisions instead of one). Is it worth it? |
||||||||
end | ||||||||
function checked_length(r::AbstractUnitRange{T}) where T<:Rational | ||||||||
f = first(r) | ||||||||
l = last(r) | ||||||||
if isempty(r) | ||||||||
return f.num - f.num | ||||||||
end | ||||||||
return div(checked_add(checked_sub(l.num, f.num), f.den), f.den) | ||||||||
end |
Uh oh!
There was an error while loading. Please reload this page.