I’ve annotated your method below with where the array allocations occur:
function myImg(pts::Integer)::Array{Float64,2}
# variables
# rotation of ellipse
aEll = 35.0/180.0*pi
axes = [1/6,1/25] # allocates a 2-element array
values = collect(linspace(-0.5,0.5,pts)) # allocates a `pts`-element array
# meshes
gridX = [i for i in values, j in values] # allocates a `pts`-by-`pts` matrix
gridY = [j for i in values, j in values] # allocates a `pts`-by-`pts` matrix
# generate ellipse
# rotate by alpha
Xr = cos(aEll).*gridX - sin(aEll).*gridY # allocates 3 `pts`-by-`pts` matrices
Yr = cos(aEll).*gridY + sin(aEll).*gridX # allocates 3 `pts`-by-`pts` matrices
img = ((1/axes[1]*Xr.^2 + 1/axes[2]*Yr.^2).<=1).*( 10*pi*Yr); # allocates 5 `pts`-by-`pts` matrices
return mod(img-pi,2*pi)+pi # allocates 3 `pts`-by-`pts` matrices
end
Now #17623 will help a little with the Xr, Yr and img lines, reducing them each to one array allocation, but @kristoffer.carlsson’s can eliminate these directly.
A few other minor points (not really performance related, but just good practice):
- Use
sindandcosdinstead ofsin(x/180.0*pi): these handle cases likesind(180)correctly (though it won’t make a huge difference in this case). - Similarly there is a
mod2pifunction, though in this case you could move the multiplication bypioutside, so the last few lines of the above solution would look like:
k = v <= 1 ? 10*Yr : 0.0
img[i,j] = (mod(k-1,2)+1)*pi