Memory allocation with function passed as arguments

The solution is rather simple: add @inline to test_calc. Then allocation is gone.

fn = (x -> 2*exp(x), x -> 2*sin(x))

@inline function test_calc(x, fn1, fn2)
    @. x = x + fn1(x) + fn2(x)
end

function test()
    A = Float64.(collect(1:10))
    @time test_calc(A,x -> 2*exp(x), x -> 2*sin(x))
    fn1, fn2 = fn
    A = Float64.(collect(1:10))
    @time test_calc(A, fn1, fn2)
    A = Float64.(collect(1:10))
    @time test_calc(A, fn...)
    return nothing
end

Run test() twice time, you get:

julia> test()
  0.000006 seconds
  0.000003 seconds
  0.000003 seconds

I haven’t observe that case in Julia 1.6 and 1.8. They both have 6 allocations (without @inline):

julia> test()
  0.000036 seconds (6 allocations: 128 bytes)
  0.000026 seconds (6 allocations: 128 bytes)
  0.000040 seconds (6 allocations: 128 bytes)

Also, if your anonymous function is complicated, you can add @inline to them to force inlining the function. like @inline(x -> 2*exp(x)).

1 Like