Julian way of preallocating arrays

Hi guys,

I’m learning Julia, and I’m trying to get things done “as Julian as possible”. My case scenario is HPC, so things have to be fast.

I’d like to preallocate work arrays that need to be used inside a function, e.g. f(u, wk1, wk2). Because this buffers are going to be allocated once and are only to be used internally by the function, i would like to keep them away from the final call and use “f” as f(u).

I thought of one ways, please let me know which are the advantages or disadvantages of using it, and/or if there are better ones

Currently I’m using a higher order function:

function GetF(N)
  wk = zeros(N)
  wk2 = zeros(N)
  function F!(u)
    # some amazing stuff that produces 0 allocations
  end
  return F!
end

F! = GetF(64) #F! Can be used

Thanks in advance!

this is fine, this is a closure, closing over variable wk and wk2

1 Like

Another way, which I find safer (perhaps only psychologically), is to define a functor:

julia> struct MyF{T}
           buffer::Vector{T}
       end

julia> (f::MyF)(x) = sum(x*b for b in f.buffer) # amazing thing with buffer

julia> const f = MyF(ones(10))
MyF{Float64}([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0])

julia> f(5)
50.0

julia> @btime f(5)
  4.770 ns (0 allocations: 0 bytes)
50.0

Internally I think both are essentially the same. But having the function as a callable structure that explicitly contains the buffers may be clearer.

(be careful in using const F! = GetF(64) or const f = MyF(...) if these things are in the global scope).

5 Likes