-
-
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
isapprox() not type-stable if called with keywords #21794
Comments
I'm pretty sure this is expected as keyword arguments are currently not very performant, see e.g. #9551. Minimal example: julia> g(x;y::Integer=5) = x+y
g (generic function with 1 method)
julia> @code_warntype g(5)
Variables:
#self#::#g
x::Int64
Body:
begin
return (Base.box)(Int64,(Base.add_int)(x::Int64,5))
end::Int64
julia> @code_warntype g(5,y=5)
Variables:
#unused#::#kw##g
#temp#@_2::Array{Any,1}
::#g
x::Int64
y::Any
...
return (x::Int64 + y::Integer)::Any
end::Any Note though that the function |
Moving forward with this - is there currently a plan to solve this? I remember @carnival had some prototype of a "named tuple" type which was targeted at this... but now I'm wondering why we shouldn't use the lowering phase to perform a trick like in the macros of NamedTuples.jl (or even just build a normal tuple and unpack it into local bindings, again via lowering). |
I admit, I don't fully understand what is going on in that issue. But one example in that thread is a keyword-function with proper type inference. Similarly, the manual suggests keyword-functions can be type stable. |
@mauro3 I don't think that's correct. The return type of |
Would this work? function isapprox(x::Number, y::Number; rtol::Real=rtoldefault(x,y), atol::Real=0, nans::Bool=false)
(x == y)::Bool || (isfinite(x) && isfinite(y) && abs(x-y) <= atol + rtol*max(abs(x), abs(y)))::Bool || (nans && isnan(x) && isnan(y))::Bool
end |
@nalimilan, yes that is true but somehow inference still fails. This is the minimal example:
But function isapprox(x::Number, y::Number; rtol::Real=rtoldefault(x,y), atol::Real=0)::Bool
x == y || (isfinite(x) && isfinite(y) && abs(x-y) <= atol + rtol*max(abs(x), abs(y)))
end (@giordano, you beat me to it.) |
Yes, we can make it type-stable (return value is inferred) but keyword arguments preclude that it is fully type-inferable (internal bindings have inferred types), both of which have a significant impact on speed. |
|
I noticed that
isapprox
allocates a lot of memory when it is called with a keyword argument, eg.Inspection with
@code_warntype
reveals a type instability. (Note theAny
on the final line.)The definition in base/floatfuncs.jl suggests it only ever returns
Bool
s. Therefore I would expect the return type to be stable.Tested on:
The text was updated successfully, but these errors were encountered: