-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Closed
Description
I've noticed this when changing find to use generators at #24774. It's likely to have a large performance impact.
julia> @code_warntype collect(v for v in [1] if v > 0)
[...]
end::Union{Array{Int64,1}, Array{Union{},1}}This type instability also affects grow_to!. I first thought it could be due to the type-instability of start(::Filter), here #temp#@_9::Union{Tuple{Bool}, Tuple{Bool,Int64,Int64}}, but artificially fixing it by making Base.Iterators.start_filter return (true, 1, 2) as the fallback does not make the problem disappear.
julia> @code_warntype Base.grow_to!(Vector{Int}(), (v for v in [1] if v > 0))
Variables:
dest::Array{Int64,1}
itr::Base.Generator{Base.Iterators.Filter{getfield(, Symbol("##104#106")),Array{Int64,1}},getfield(, Symbol("##103#105"))}
out::Any
s::Int64
v<optimized out>
t<optimized out>
#temp#@_9::Union{Tuple{Bool}, Tuple{Bool,Int64,Int64}}
#temp#@_10::Any
#temp#@_11::Bool
[...]
#= line 397 =#
#temp#@_9::Union{Tuple{Bool}, Tuple{Bool,Int64,Int64}} = (true,)
59:
# meta: pop location
SSAValue(17) = #temp#@_9::Union{Tuple{Bool}, Tuple{Bool,Int64,Int64}}
# meta: pop locations (2)
SSAValue(50) = (SSAValue(17) isa Tuple{Bool})::Bool
unless SSAValue(50) goto 67
#temp#@_10::Any = $(Expr(:invoke, MethodInstance for grow_to!(::Array{Union{},1}, ::Base.Generator{Base.Iterators.Filter{getfield(, Symbol("##104#106")),Array{Int64,1}},getfield(, Symbol("##103#105"))}, ::Tuple{Bool}), :(Base.grow_to!), SSAValue(11), :(itr), SSAValue(17)))::Union{Array{Int64,1}, Array{Union{},1}}
goto 76
67:
SSAValue(51) = (SSAValue(17) isa Tuple{Bool,Int64,Int64})::Bool
unless SSAValue(51) goto 72
#temp#@_10::Any = $(Expr(:invoke, MethodInstance for grow_to!(::Array{Union{},1}, ::Base.Generator{Base.Iterators.Filter{getfield(, Symbol("##104#106")),Array{Int64,1}},getfield(, Symbol("##103#105"))}, ::Tuple{Bool,Int64,Int64}), :(Base.grow_to!), SSAValue(11), :(itr), SSAValue(17)))::Union{Array{Int64,1}, Array{Union{},1}}
[...]
return dest::Array{Int64,1}
96:
return out::Any
end::Union{Array{Int64,1}, Array{Union{},1}}
julia> @code_warntype Base.grow_to!(Vector{Int}(), (v for v in [1] if v > 0), (false, 1, 2))
[...]
end::Array{Int64,1}
julia> @code_warntype Base.grow_to!(Vector{Int}(), (v for v in [1] if v > 0), (false,))
[...]
end::Array{Int64,1}So the explanation might be that the function could theoretically return new rather than dest, and that new could have its type change in the loop. This might confuse inference when grow_to!(dest, itr) is inlined in grow_to!(dest, itr). I've tried using @noinline, but it doesn't appear to have an effect here.
Metadata
Metadata
Assignees
Labels
No labels