Well, actually this statement is technically not quite true. Option 2 does actually carry the potential for a performance difference. The Fix2 object only specializes on the type of par, not the value of par, so using it can block constant propagation of par’s value in some circumstances.
Here’s an example where an anonymous function results in more efficient code than Fix2:
foo(f,a,b) = f(1) ? a / b : b / a;
greater_than_1(x) = x > 1;
This is efficient:
julia> @code_llvm debuginfo=:none foo(greater_than_1, 1, 2)
; Function Signature: foo(typeof(Main.greater_than_1), Int64, Int64)
define double @julia_foo_4589(i64 signext %"a::Int64", i64 signext %"b::Int64") #0 {
top:
%0 = sitofp i64 %"b::Int64" to double
%1 = sitofp i64 %"a::Int64" to double
%2 = fdiv double %0, %1
ret double %2
}
This is less efficient:
julia> @code_llvm debuginfo=:none foo(Base.Fix2(>, 1), 1, 2)
; Function Signature: foo(Base.Fix{2, typeof(Base.:(>)), Int64}, Int64, Int64)
define double @julia_foo_4592(ptr nocapture noundef nonnull readonly align 8 dereferenceable(8) %"f::Fix", i64 signext %"a::Int64", i64 signext %"b::Int64") #0 {
top:
%"f::Fix.unbox" = load i64, ptr %"f::Fix", align 8
%0 = icmp sgt i64 %"f::Fix.unbox", 0
br i1 %0, label %L8, label %L4
common.ret: ; preds = %L8, %L4
%common.ret.op = phi double [ %3, %L4 ], [ %6, %L8 ]
ret double %common.ret.op
L4: ; preds = %top
%1 = sitofp i64 %"a::Int64" to double
%2 = sitofp i64 %"b::Int64" to double
%3 = fdiv double %1, %2
br label %common.ret
L8: ; preds = %top
%4 = sitofp i64 %"b::Int64" to double
%5 = sitofp i64 %"a::Int64" to double
%6 = fdiv double %4, %5
br label %common.ret
}