-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Description
The julia documentation says (https://docs.julialang.org/en/v1/manual/performance-tips/#Be-aware-of-when-Julia-avoids-specializing):
As a heuristic, Julia avoids automatically specializing on argument type parameters in three specific cases:
Type
,Function
, andVararg
. Julia will always specialize when the argument is used within the method, but not if the argument is just passed through to another function.
Surprisingly, this behavior seems to change if we give that method parameter a declared type of ::Union{Function, Nothing}
:
$ julia --trace-compile=stderr -e '@noinline f1(f, x) = Any[f, x]; f2(x) = f1(+, Any[x][1]); f2(1)'
precompile(Tuple{typeof(Main.f2), Int64})
precompile(Tuple{typeof(Main.f1), Function, Int64})
$ julia --trace-compile=stderr -e '@noinline f1(f::Function, x) = Any[f, x]; f2(x) = f1(+, Any[x][1]); f2(1)'
precompile(Tuple{typeof(Main.f2), Int64})
precompile(Tuple{typeof(Main.f1), Function, Int64})
$ julia --trace-compile=stderr -e '@noinline f1(f::Union{Function, Nothing}, x) = Any[f, x]; f2(x) = f1(+, Any[x][1]); f2(1)'
precompile(Tuple{typeof(Main.f2), Int64})
precompile(Tuple{typeof(Main.f1), typeof(Base.:(+)), Int64})
As you can see, this is extra surprising because it works as described with no type restrictions at all: f1(f::Any, x) =
works fine, but f1(f::Union{Function, Nothing}, x)
does not.
This is a bug, right?
I confirmed this same behavior on both julia 1.10 and julia nightly.