-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
improve performance of isapprox(::AbstractArray, ::AbstractArray)
when rtol = 0
#47464
Conversation
Nice!
That cost seems negligible for all array sizes to me. That part if this PR looks ready to merge to me. For the part about atol's type, is there a case where |
After making this PR, I realized that the change to julia> f(;x, y) = x>0 ? x : y
julia> @code_warntype f(;x=0, y=0.0)
MethodInstance for (::var"#f##kw")(::NamedTuple{(:x, :y), Tuple{Int64, Float64}}, ::typeof(f))
[...]
Body::Union{Float64, Int64} So the change to This also poses a problem if a call now explicitly has The problem is complicated by the fact that it is possible to change the used norm via the Here's a suggestion for that - would love to hear thoughts: [...]
d = norm(x - y)
if isfinite(d)
T = promote_type(typeof(atol), typeof(rtol*d))
rtol = convert(T, rtol)
atol = convert(T, atol)
tol = iszero(rtol) ? atol : max(atol, rtol*max(norm(x), norm(y))) # <--- now `tol` should be type-stable
return d <= tol
else |
Okay, that should solve my worry about dynamic dispatch, thanks @LilithHafner. I think it's fine to keep the more refined |
I'd still like to see an example where this increased complexity for |
Okay, we can keep the original The current asymmetry between the care taken with the types of But those details are orthogonal to the main point of this PR, so let's just go with the original |
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.
Improving the default atol
to obviate that definition in Unitful.jl would be a nice contribution in a different PR.
This one looks good to me as it. Thanks!
Co-authored-by: Lilith Orion Hafner <[email protected]>
de7b80a
to
202d1aa
Compare
CI failures look unrelated |
The default value of
rtol
forisapprox
depends on whetheratol
is zero or not; ifatol
is nonzero,rtol
is zero (#22742).The "normal-path"
isapprox(x, y; atol, rtol
check is justnorm(x-y) <= max(atol, rtol*max(norm(x), norm(y)))
. Ifrtol = 0
, however, we are then redundantly computing the norm of bothx
andy
, which can be expensive for arrays (unlike numbers).This change simply puts a branch in to check
iszero(rtol)
: if so, it avoids computing the norms redundantly. This speeds upisapprox(X, Y; atol ≠ 0)
considerably:The cost of the extra branch is not nothing, of course, but should be negligible in the context of other costs for most array sizes.
There's also a small change to the
atol
default value: I noticed that care was being taken to initializertol
to a type consistent withx
andy
; I figured the same might as well be done foratol
.