Avoiding memory allocation when repeatedly using small arrays

For some reason the where N in f(x) is causing allocations:

julia> f(x) where N = √sum(abs2,x .- 2^6) - 2^5
f (generic function with 1 method)

julia> @btime f($x)
  22.725 ns (2 allocations: 48 bytes)
78.32565875726226

julia> f(x) = √sum(abs2,x .- 2^6) - 2^5
f (generic function with 1 method)

julia> @btime f($x)
  5.862 ns (0 allocations: 0 bytes)
78.32565875726226

I had to change that to get what you report:

julia> @benchmark oint($f,$n_auto,$p)
BechmarkTools.Trial: 10000 samples with 1 evaluations.
 Range (min … max):  114.826 μs … 284.301 μs  ┊ GC (min … max): 0.00% … 0.00%
 Time  (median):     115.015 μs               ┊ GC (median):    0.00%
 Time  (mean ± σ):   117.534 μs ±   9.510 μs  ┊ GC (mean ± σ):  0.00% ± 0.00%

  █ ▁     ▁   ▁                                             ▁   ▁
  █▆█▆▇▇▆▆█▃▄▃█▄▁▄▁▇▆▇▇▇▇▅▅▆▅▇▅▅▆▅▇▆▃▅▅▅▇▆▆▆▅▅▆▆▅▆▅▅▅█▄▅▅▅▅▇█▇▆ █
  115 μs        Histogram: log(frequency) by time        160 μs <

 Memory estimate: 96 bytes, allocs estimate: 1.

Then, with these changes, you get 0 allocations:

julia> function oint(f,n,p::Array{T,N}) where {T,N}
           s = zeros(SVector{N,T}) # static vector here
           for I ∈ CartesianIndices(p)
               x = SVector{N,T}(ntuple(i->I[i],N)) # initialize svector with size defined at compile time
               d = f(x)::Float64
               abs(d) ≤ 1 && (s += n(x).*p[I]*(1+cos(π*d))/2) # remove a dot in s .+=
           end
           return s
       end
oint (generic function with 1 method)

julia> @benchmark oint($f,$n_auto,$p)
BechmarkTools.Trial: 10000 samples with 1 evaluations.
 Range (min … max):  105.190 μs … 221.240 μs  ┊ GC (min … max): 0.00% … 0.00%
 Time  (median):     105.372 μs               ┊ GC (median):    0.00%
 Time  (mean ± σ):   107.170 μs ±   7.259 μs  ┊ GC (mean ± σ):  0.00% ± 0.00%

  █      ▃▂    ▁                                                ▁
  █▆▅▆▇████▆▆▄▅█▄▁▄▆▆▄▅▄▅▇▅▅▅▅▇▁▅▃▃▄▇▄▃▄▅▄▇▅▅▄▅▃▇▄▃▅▃▄▄▇▄▅▃▃▄▅█ █
  105 μs        Histogram: log(frequency) by time        145 μs <

 Memory estimate: 0 bytes, allocs estimate: 0.


3 Likes