julia> code_warntype(+,(typeof(1m),typeof(1m)))
Variables:
#self#::Base.#+
x::Unitful.RealQuantity{Int64,Unitful.UnitData{(m,)}}
y::Unitful.RealQuantity{Int64,Unitful.UnitData{(m,)}}
Body:
begin # /home/jas/.julia/v0.5/Unitful/src/Unitful.jl, line 321:
return $(Expr(:new, Unitful.RealQuantity{Int64,Unitful.UnitData{(m,)}}, :((Base.box)(Int64,(Base.add_int)((top(getfield))(x::Unitful.RealQuantity{Int64,Unitful.UnitData{(m,)}},:val)::Int64,(top(getfield))(y::Unitful.RealQuantity{Int64,Unitful.UnitData{(m,)}},:val)::Int64)))))
end::Unitful.RealQuantity{Int64,Unitful.UnitData{(m,)}}
and
@benchmark 1m+1cm shows 0 bytes were allocated
for your code
julia> code_warntype(+,(typeof(1m),typeof(1m)))
Variables:
a::Meter{1,0}
b::Meter{1,0}
mag::Int64
aval::Any
bval::Any
#s4::Int64
Body:
begin # none, line 4:
GenSym(0) = (Main.normalize)(a::Meter{1,0},b::Meter{1,0})::Tuple{Int64,Any,Any}
#s4 = 1
GenSym(4) = (Base.getfield)(GenSym(0),1)::Any
GenSym(5) = (Base.box)(Base.Int,(Base.add_int)(1,1))
mag = GenSym(4)
#s4 = GenSym(5)
GenSym(6) = (Base.getfield)(GenSym(0),2)::Any
GenSym(7) = (Base.box)(Base.Int,(Base.add_int)(2,1))
aval = GenSym(6)
#s4 = GenSym(7)
GenSym(8) = (Base.getfield)(GenSym(0),3)::Any
GenSym(9) = (Base.box)(Base.Int,(Base.add_int)(3,1))
bval = GenSym(8)
#s4 = GenSym(9) # none, line 5:
return call((top(apply_type))(Main.Meter,1,mag::Int64)::Type{_<:Meter{1,magnitude}},aval + bval::Any)::Meter{d,magnitude}
end::Meter{d,magnitude}
and
@benchmark 1m+1m show 48 bytes allocated
Anything code_warntype highlights indicates type ambiguity or lack of type specialization; that derails multidispatched specialization, and so costs time. And code that does not allocate memory is, in a sense, doing more with less -- or doing more earlier, so it does less at runtime.