I've found that the performance of cell Arrays, multi-dimensional arrays, and structure arrays are all far slower than the use of multiple independent variables. Thus, my optimized codes have been using super long if-statements and functions which completely write out which variables are needed or not. The code is thus faster than using the other methods, but the code is also quite messy. A reproduction of the independent variables approach using 'eval' also doesn't work because of the way eval is executed by MATLAB.
Is there another way to do this without writing out each variable? Perhaps there I could use cell arrays but pass an argument which results in MATLAB treating them in a faster way… This might not seem like a big deal, but my codes take dozens of hours to execute (itt>1000), which becomes many days when the other 'MATLAB-preferred' methods are used.
Here is a code showing this performance. Values of ytessel and xtessel can be changed as you please, but changing these values requires manually changing the code for the fastest method (independent variables).
%%model prep
ytessel = 4; xtessel = 4; nnum = 72*1; ynum = nnum*ytessel; xnum = nnum*xtessel; itt = 5; totemit = rand(ynum,xnum); T = zeros(ynum,xnum); for y=1:nnum for x=1:nnum dT_depot{y,x} = rand(ynum,xnum); end end %%CELL ARRAYS
tic for i=1:itt for yt=1:ytessel for xt=1:xtessel A{yt,xt} = zeros(ynum,xnum); end end for y=1:nnum for x=1:nnum dT = dT_depot{y,x}; for yt=1:ytessel for xt=1:xtessel A{yt,xt} = A{yt,xt} + dT.*totemit(y+(yt-1)*nnum,x+(xt-1)*nnum); end end end end end disp(sprintf('Time: %f (Cell Array Method)',toc)); %%4D Matrix
tic for i=1:itt C = zeros(ynum,xnum,ytessel,xtessel); for y=1:nnum for x=1:nnum for yt=1:ytessel for xt=1:xtessel dT = dT_depot{y,x}; C(:,:,yt,xt) = C(:,:,yt,xt) + dT.*totemit(y+(yt-1)*nnum,x+(xt-1)*nnum); end end end end end disp(sprintf('Time: %f (4D Array Method)',toc)); %%Independent Variables
D11 = zeros(ynum,xnum); D12 = zeros(ynum,xnum); D13 = zeros(ynum,xnum); D14 = zeros(ynum,xnum); D21 = zeros(ynum,xnum); D22 = zeros(ynum,xnum); D23 = zeros(ynum,xnum); D24 = zeros(ynum,xnum); D31 = zeros(ynum,xnum); D32 = zeros(ynum,xnum); D33 = zeros(ynum,xnum); D34 = zeros(ynum,xnum); D41 = zeros(ynum,xnum); D42 = zeros(ynum,xnum); D43 = zeros(ynum,xnum); D44 = zeros(ynum,xnum); tic for i=1:itt D11(:) = 0; D12(:) = 0; D13(:) = 0; D14(:) = 0; D21(:) = 0; D22(:) = 0; D23(:) = 0; D24(:) = 0; D31(:) = 0; D32(:) = 0; D33(:) = 0; D34(:) = 0; D41(:) = 0; D42(:) = 0; D43(:) = 0; D44(:) = 0; for y=1:nnum for x=1:nnum curdepot = dT_depot{y,x}; D11 = D11 + curdepot.*totemit(y, x); D21 = D21 + curdepot.*totemit(y+nnum, x); D31 = D31 + curdepot.*totemit(y+nnum*2,x); D41 = D41 + curdepot.*totemit(y+nnum*3,x); D12 = D12 + curdepot.*totemit(y, x+nnum); D22 = D22 + curdepot.*totemit(y+nnum, x+nnum); D32 = D32 + curdepot.*totemit(y+nnum*2,x+nnum); D42 = D42 + curdepot.*totemit(y+nnum*3,x+nnum); D13 = D13 + curdepot.*totemit(y,x+nnum*2); D23 = D23 + curdepot.*totemit(y+nnum,x+nnum*2); D33 = D33 + curdepot.*totemit(y+nnum*2,x+nnum*2); D43 = D43 + curdepot.*totemit(y+nnum*3,x+nnum*2); D14 = D14 + curdepot.*totemit(y,x+nnum*3); D24 = D24 + curdepot.*totemit(y+nnum,x+nnum*3); D34 = D34 + curdepot.*totemit(y+nnum*2,x+nnum*3); D44 = D44 + curdepot.*totemit(y+nnum*3,x+nnum*3); end end end disp(sprintf('Time: %f (Independent Variables Method)',toc)); %%STRUCT ARRAYS
for yt=1:ytessel for xt=1:xtessel DD(yt,xt).dat = zeros(ynum,xnum); end end tic for i=1:itt for yt=1:ytessel for xt=1:xtessel DD(yt,xt).dat = zeros(ynum,xnum); end end for y=1:nnum for x=1:nnum curdepot = dT_depot{y,x}; for yt=1:ytessel for xt=1:xtessel DD(yt,xt).dat = DD(yt,xt).dat + curdepot.*totemit(y+(yt-1)*nnum,x+(xt-1)*nnum); end end end end end disp(sprintf('Time: %f (Structure Arrays Method)',toc)); %%Eval Method
for yt=1:ytessel for xt=1:xtessel eval(['D' num2str(yt) num2str(xt) '=zeros(ynum,xnum);']); end end tic for i=1:itt for yt=1:ytessel for xt=1:xtessel eval(['D' num2str(yt) num2str(xt) '(:)=0;']); end end for y=1:nnum for x=1:nnum curdepot = dT_depot{y,x}; for yt=1:ytessel for xt=1:xtessel eval(['D' num2str(yt) num2str(xt) '=D' num2str(yt) num2str(xt) '+curdepot.*totemit(y+nnum*' num2str(yt-1) ',x+nnum*' num2str(xt-1) ');']); end end end end end disp(sprintf('Time: %f (Eval Method)',toc));
Output:
Time: 16.279780 (Cell Array Method) Time: 79.975502 (4D Array Method) Time: 7.808595 (4D Independent Variables Method) Time: 20.406543 (Structure Arrays Method) Time: 127.129048 (Eval Method)
Best Answer