-
-
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
foo(x::Tuple{Vararg})
specializes much more aggressively than foo(x...)
#54390
Comments
foo(x::Tuple{Vararg})
specialized much more aggressively than foo(x...)
foo(x::Tuple{Vararg})
specializes much more aggressively than foo(x...)
To make the motivation here a bit more concrete, we have code in Base that uses Lines 83 to 84 in 1614e11
Ironically, this code ends up iterating over Lines 59 to 68 in 1614e11
Why is the unrolled Tuple information "useless" here? This loop is not statically unrolled, so a specialized instance of the function (e.g. That argument disregards codegen/ABI details, which could motivate specialization (e.g. to get fixed-size arguments), but for any polymorphic call-sites, i.e. call-sites where we don't know exactly what Tuple they'll pass in, de-specialization would be a clear win for this code. |
This would be disruptive for performance-focused packages. And kinda breaking. It's well known and documented that Julia almost always specializes on argument type. The performance tips document that there are exactly three exceptions. |
This is specifically about |
I would (var)argue that EDIT: this is to emphasize that As for the |
Using a In any case, the root of the issue is that there's currently no way to ask Julia to specialize |
One also can't have an Just like julia> Tuple{Vararg{Int64,3}}
Tuple{Int64, Int64, Int64} Maybe one could go deep into the compiler to make specific exceptions when If you want collections that don't specialize on length, use |
Why does it need to dispatch on the order of the combination of Int/String types of it? Often we deal with this sort of situation by making it just accept any Tuple, then using a type assert inside (if necessary) to provide diagnostics if the user accidentally passes something else |
Yeah, that's an interesting thought. We could de-specialize completely on the |
Consider these two very similar functions:
The
foo_vararg
function limits the amount it specializes on length (an escape hatch was also added in #49172 to control this per-method, if necessary):In contrast,
foo_vararg_tuple
specializes on every permutation/length of tuple it receives:This over-specialization can often lead to type-unstable code and dynamic dispatches.
A better alternative I think would be to unroll this
Vararg
much less aggressively by default. We would still provide fullVararg
unwrapping if you provide an explicitwhere
hint, as infoo(::Tuple{Vararg{Union{AbstractString,Integer}, N}}) where N
.We already recommend that escape hatch in the performance tips for the
foo(x...)
case.The text was updated successfully, but these errors were encountered: