That explanation is a bit off actually, it's not that f1 can't optimize for 
t, it's that f1 has to do method lookup every time it's called.


  type X; x::Int end
  g1(x) = x.x+1
  g2(x::X) = x.x+1

  x = X(1)
  const y = X(1)

  @code_warntype g1(x)
  #...
  #  begin 
  #    return 
(Base.box)(Int64,(Base.add_int)((Core.getfield)(x::X,:x)::Int64,1))
  #  end::Int64

  @code_warntype g2(x)
  #...
  #  begin
  #    return 
(Base.box)(Int64,(Base.add_int)((Core.getfield)(x::X,:x)::Int64,1))
  #  end::Int64

  # same generated code, but...

  h1() = g1(x)
  h2() = g2(x)

  @code_warntype h1()
  #  ...
  #  begin 
  #    SSAValue(0) = Main.x
  #    return ((Core.getfield)(SSAValue(0),:x)::Any + 1)::Any
  #  end::Any

  @code_warntype h2()
  #  ...
  #  begin 
  #    return (Main.g2)(Main.x)::Int64
  #  end::Int64

  # The specialized method can't be found beforehand on h1!

  @timeit h1()
  #  1000000 loops, best of 3: 228.03 ns per loop
  #  2.28028349e-7

  @timeit h2()
  #  1000000 loops, best of 3: 185.79 ns per loop
  #  1.85790018e-7


You probably already know this, but correcting my wrong info and explaining 
it makes me feel better :P

Reply via email to