Apparent mismatch of run times during summation

Hm, when checking this I noticed

f1=x->1/(x^2+1)
f2=x->1/(x^2+im)

using BenchmarkTools

println("lambda")
@btime f1(Ref(x)[]) setup=(x=1)
@btime f2(Ref(y)[]) setup=(y=2)
@btime f2(Ref(x)[]) * f2(Ref(y)[]) setup=(x=1; y=2)
@btime sum(f1(x) for x in 1:100) 
@btime sum(f2(x) for x in 1:100)
@btime sum(f1(x) * f2(x) for x in 1:100)

g1(x)=1/(x^2+1)
g2(x)=1/(x^2+im)

using BenchmarkTools

println("function")
@btime g1(Ref(x)[]) setup=(x=1)
@btime g2(Ref(y)[]) setup=(y=2)
@btime g2(Ref(x)[]) * g2(Ref(y)[]) setup=(x=1; y=2)
@btime sum(g1(x) for x in 1:100) 
@btime sum(g2(x) for x in 1:100)
@btime sum(g1(x) * g2(x) for x in 1:100)

yields

lambda
  24.598 ns (1 allocation: 16 bytes)
  40.262 ns (1 allocation: 32 bytes)
  96.832 ns (3 allocations: 96 bytes)
  4.757 μs (199 allocations: 3.11 KiB)
  6.200 μs (199 allocations: 6.22 KiB)
  10.900 μs (399 allocations: 10.91 KiB)
function
  4.300 ns (0 allocations: 0 bytes)
  19.238 ns (0 allocations: 0 bytes)
  36.052 ns (0 allocations: 0 bytes)
  96.733 ns (0 allocations: 0 bytes)
  1.910 μs (0 allocations: 0 bytes)
  2.089 μs (0 allocations: 0 bytes)

Is this expected or am I doing it wrong (again;)?

Edit: ah, I see, const-ing the lambda functions

const f1=x->1/(x^2+1)
const f2=x->1/(x^2+im)

shows the expected performance.

1 Like