I’m working on some code that should iterate over milti-dimensional space, where the dimension dim
is provided as a parameter to the function. The simplest approach I found is to use CartesianRange, like in the following simple example:
function test1(dim::Int)
imin=fill(0, dim)
imax=fill(0, dim)
accumulator = 0
for k = 1:10000
rand!(imin, 1:5)
rand!(imax, 1:5)
for c in CartesianRange(CartesianIndex(imin...), CartesianIndex(imax...))
# do something with c, e.g
accumulator += c.I[1]+c.I[2]
end
end
return accumulator
end
While this works great, there is a finite memory allocation for each splatting imin… and imax…
@time test1(2);
0.191940 seconds (179.32 k allocations: 5.626 MB)
For the real application, this alone can exhaust my available memory, as many such multidimensional loops are required.
A very similar function with “hard-coded” dim=2 completely avoids this problem, and is also much faster
function test2()
imin=fill(0, 2)
imax=fill(0, 2)
accumulator = 0
for k = 1:10000
rand!(imin, 1:5)
rand!(imax, 1:5)
for c in CartesianRange(CartesianIndex(imin[1],imin[2]), CartesianIndex(imax[1],imax[2]))
# do something with c, e.g
accumulator += c.I[1]+c.I[2]
end
end
return accumulator
end
0.001797 seconds (7 allocations: 368 bytes)
Now the question: is it possible to avoid this multidimensional loop allocation without sacrificing hard-coding the dimensions and the splatting of the CartesianRange?
Cheers!