-
-
Couldn't load subscription status.
- Fork 5.7k
digits!: check for typemax only when applicable #16844
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
base/intfuncs.jl
Outdated
| function digits!{T<:Integer}(a::AbstractArray{T,1}, n::Integer, base::Integer=10) | ||
| 2 <= base || throw(ArgumentError("base must be ≥ 2, got $base")) | ||
| base - 1 <= typemax(T) || throw(ArgumentError("type $T too small for base $base")) | ||
| !applicable(typemax, T) || |
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.
why not applicable(typemax, T) && ...?
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.
Because then the second branch of the && must be parenthesized (one more character, you know!)
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.
Would it be clearer if I change the test to:
applicable(typemax, T) &&
base - 1 > typemax(T) && throw(ArgumentError("type $T too small for base $base"))
?
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.
I'm not sure we really want to call applicable here: based on the @code_llvm it doesn't seem to be evaluated only at compile time. Unless anyone can think of something better, it might be better to just have T == BigInt || base-1 <= typemax(T) || ...
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.
Oh, I didn't expect that to be a performance problem, but still it seems to be reasonable (of the order of 30 percent penalty for small numbers). I just tried with method_exists instead, but this is far worse. I don't like the T == BigInt solution, as it doesn't handle number types defined outside of Base.
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.
See #16422. What do you mean by "far worse"?
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.
Ah thanks, I had seen that one but totally forgot about it. As @timholy seemed to want it merged soon, I will update this PR using method_exists, and hope for the best. For now, this is one order of magnitude slower (for the digits of small numbers).
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.
I think that issue has a high chance of getting closed without merging, as @timholy noted in reply to Jameson's comments on its dangerous implementation.
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.
OK so let's not hold our breath. I just tried a new version where I replace applicable by hastypemax defined as follows:
hastypemax{T<:Base.BitInteger}(::Type{T}) = true
hastypemax{T<:BigInt}(::Type{T}) = false
hastypemax(::Type{T}) = applicable(typemax, T)
The perfs seem to be similar to the base version, maybe few percents behind (hastypemax may be not removed at compilation time?). But it's a bit ugly, I'd rather wait for applicable (or method_exists) to be improved, and pay 30% penalty in the meantime. But if someone thinks it's important to preserve every bit of efficiency in digits!, I will update with this hastypemax function.
|
Related to #7501. |
d7d5736 to
078b81f
Compare
|
I updated with the |
|
This is a bugfix, so it should be backportable; however, it does introduce a new internal trait. How do you feel about potentially backporting this, @tkelman? |
|
None of the existing traits would cover this? |
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.
superficially lgtm (i.e. modulo @tkelman's hastypemaxquestion)! :)
|
Some of them are starting to get added in |
I think yes, partially. But as you say, this would require to change |
|
Will merge within one or two days, if no objection. |
|
This looks like another case where a trait would not really be needed if |
No description provided.