Search code examples
functioncompilationjuliaspecialization

Does specialization happen with or without a type annotation?


Documentation:

Argument-type declarations normally have no impact on performance: regardless of what argument types (if any) are declared, Julia compiles a specialized version of the function for the actual argument types passed by the caller. For example, calling fib(1) will trigger the compilation of specialized version of fib optimized specifically for Int arguments, which is then re-used if fib(7) or fib(15) are called.

The provided example:

fib(n::Integer) = n ≤ 2 ? one(n) : fib(n-1) + fib(n-2)

but then in the Performance Tips:

# This will not specialize:

function f_type(t)  # or t::Type
    x = ones(t, 10)
    return sum(map(sin, x))
end

From my understanding of the performance tips, with or without type annotations fib(b::Integer) or fib(b) shouldn't specialize specifically for Int arguments.

It seems with or without the type annotation no specialization will happen, but why does the manual seem to indicate that it will specialize?


Solution

  • The example in the Performance Tips page is about the specific case where you pass the type itself as the argument to the function. As the beginning of that section says:

    Julia avoids automatically specializing on argument type parameters in three specific cases: Type, Function, and Vararg

    f_type in that example is a function that accepts a Type t. A call to that function will look like, for eg., f_type(Int). The section says that type specialization isn't done based on the Int type in this case, where the Int is passed as a value of the parameter itself (and then passed through to another function). (Specifically, the Type isn't specialized into a specific parametrized type like Type{Int}, as it normally would be if the argument wasn't one of the above mentioned three cases.)

    This doesn't apply to the fib method (or most methods we normally define). fib accepts a value whose type is (a subtype of) Integer, not the type itself. In such cases, a call like fib(1) or fib(UInt8(2)) does create type-specialized compiled versions of the function.