Home > Software design >  Does specialization happen with or without a type annotation?
Does specialization happen with or without a type annotation?

Time:06-30

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?

CodePudding user response:

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, and will be called as, 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).

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.

CodePudding user response:

In layman words, Julia will always specialize on function arguments either with or without annotation, except in three cases. One of them is when the arguments are passed to another function, since specializing twice will slow compilation down, and it will finally be specialized at the inner function call, so no performance hit occurs.

So, fib(n:Int) is equivalent to fib(n) and both will use a specialized compiled version of the function for the Int64 type unless n is already of a different type than Int64, it will specialize for that type.

  • Related