Performance of type annotations

Docs say that type annotations on variables and return types of functions facilitate type inference and performance. But does the opposite hold? If I have a function:

function foo(x)::Number
    if isa(x, Number)
        return x
    else
        return 0
    end
end

Will the convert(Number, ...) method be called on the return value of foo, or it will be a no-op, for it is clear that both x and 0 are Numbers?

In general, if I have a variable with type annotation, is convert called at every assignment to the variable or it optimized away whenever type inference is sure about the type of RHS?

Julia has excellent tools to answer those questions :slight_smile:
E.g. use @code_warntype and @code_lowered to figure out what happens (you can use ?@code_lowered in the REPL to get the doc string for those macros):


julia> function foo(x)::Number
           if isa(x, Number)
               return x
           else
               return 0
           end
       end
foo (generic function with 1 method)

julia> @code_lowered foo(1)
CodeInfo(:(begin 
        nothing
        SSAValue(0) = Main.Number
        unless x isa Main.Number goto 6 # line 3:
        return (Core.typeassert)((Base.convert)(SSAValue(0), x), SSAValue(0))
        6:  # line 5:
        return (Core.typeassert)((Base.convert)(SSAValue(0), 0), SSAValue(0))
    end))

julia> @code_warntype foo(1)
Variables:
  #self# <optimized out>
  x::Int64

Body:
  begin  # line 3:
      return x::Int64 # line 5:
  end::Int64

julia> @code_warntype foo(1.0)
Variables:
  #self# <optimized out>
  x::Float64

Body:
  begin  # line 3:
      return x::Float64 # line 5:
  end::Float64

julia> @code_warntype foo("1")
Variables:
  #self# <optimized out>
  x <optimized out>

Body:
  begin 
      goto 3 # line 3:
      3:  # line 5:
      return 0
  end::Int64

So Julia seems to turn each return into convert(Number, x)::Number. The type assert and convert get inlined and removed.

@sdanisch Indeed, thanks a lot!