I put together a test function to bring out some more specific details about dynamic allocation. The function used is at the bottom of the answer.
The function calls several location functions that compute the y value from the input x value of variable length with logarithmic diversity. Functions are different, but the type of cycle ( for and while ) and the distribution scheme (dynamic and preliminary allocation). Results taken from R2014b. Below are the results that have passed using four functions.
For a low number of items, the execution time is constant; to count high elements, all four functions enter the growth mode with similar growth rates. Adjusting the data power (i.e., c = ArgMin[c(1)*n^c(2) - time] ) returns an exponent in the range from 0.93 to 0.96 (linear growth) over four data sets.
I am really surprised at these results, because either I'm missing something in the test, or the Matlab JIT compiler is really good at distributing arrays (possibly related lists under the hood). The pre-allocated for -loop worked faster, but only 12% faster than the dynamic version.

Turning to memory consumption, I launched dynamic and pre-allocated versions of the for -loop option for several linearly increasing elements in the ten million element range. The total memory used by Matlab was selected at the beginning and end of the cycles. The results are shown below.
As shown, the initial memory for function calls is identical (for the most part) between the two functions. The memory usage for the pre-allocated version increases linearly with the element count, which is expected. But the memory used for the dynamic version, although piecewise-ruled, has a tendency to jump-like rearrangement at several points. For me, this implies that Matlab does some form of table growth (not necessarily doubling the table, as I think Python), so as not to redistribute the array at each iteration (which makes me think about my thought about linked lists from the above discussion time).

I found these results interesting, but I really canβt conclude much more for the thoughts above. However, regardless of anything, explicit pre-allocation will always be better for runtime and maintenance of the code in any numerical heavy application.
Any comments on the results and the test function (perhaps a discussion of how this test just goes wrong) are, of course, welcome. This is how I (we) learn.
function [] = test() % Constants and setup funs = {@forDynamic,@forAllocate,@whileDynamic,@whileAllocate}; Nfun = numel(funs) ; % Nalloc = 2E7 ; Nsamp = 50 ; % x = linspace(0,1,Nalloc) ; nIndex = round(logspace(1,log10(Nalloc),Nsamp)) ; times = repmat({zeros(1,Nsamp)},1,Nfun) ; % Array growth time-data for k = 1:numel(funs) f = funs{k}; for m = 1:Nsamp tic; f(x(1:nIndex(m))); times{k}(m) = toc; fprintf(['Iteration ',num2str(m,'%02G'),' of function ',num2str(k),' done.\n']); end end % Plot figure(1); args(2:2:2*Nfun) = times; args(1:2:2*Nfun) = repmat({nIndex},1,Nfun); loglog(args{:}); legend('Dynamic Allocation (for)','Pre-Allocation (for)','Dyanmic Allocation (while)','Pre-Allocation (while)','Location','Northwest'); grid('on'); axis([nIndex(1),nIndex(end),0.95*min([times{:}]),1.05*max([times{:}])]); xlabel('Number of Array Elements [-]'); ylabel('Elasped Time [s]'); % Switch to linear scale near allocation max and only look at for-functions Nsamp = 50 ; nIndex = round(10.^linspace(log10(Nalloc)-1.5,log10(Nalloc),Nsamp)) ; mstart = repmat({zeros(1,Nsamp)},1,Nfun/2) ; mend = repmat({zeros(1,Nsamp)},1,Nfun/2) ; % Array growth memory-data for k = 1:numel(funs)/2 f = funs{k}; for m = 1:Nsamp [~,mstart{k}(m),mend{k}(m)] = f(x(1:nIndex(m))); fprintf(['Iteration ',num2str(m,'%02G'),' of function ',num2str(k),' done.\n']); end end % Plot figure(2); mem = [mstart,mend]; args(2:2:2*Nfun) = mem ; args(1:2:2*Nfun) = repmat({nIndex},1,Nfun); h = plot(args{:}); set(h([1,2]),'LineStyle','--'); set(h([1,3]),'Color','k'); set(h([2,4]),'Color','r'); legend('Dynamic Allocation Start','Pre-Allocation Start','Dynamic Allocation End','Pre-Allocation End','Location','Northwest'); grid('on'); axis([nIndex(1),nIndex(end),0.95*min([mem{:}]),1.05*max([mem{:}])]); xlabel('Number of Array Elements [-]'); ylabel('Matlab Memory Usage [MB]'); end function y = burden(x) y = besselj(0,x); end function mem = getMemory() mem = memory(); mem = mem.MemUsedMATLAB/1E6; %[MB] end function [y,mstart,mend] = forDynamic(x) mstart = getMemory(); n = numel(x) ; for k = 1:n y(k) = burden(x(k)); end mend = getMemory(); end function [y,mstart,mend] = forAllocate(x) mstart = getMemory(); n = numel(x) ; y(1,n) = 0 ; for k = 1:numel(x) y(k) = burden(x(k)); end mend = getMemory(); end function [y,mstart,mend] = whileDynamic(x) mstart = getMemory(); n = numel(x) ; k = 1 ; while k <= n y(k) = burden(x(k)) ; k = k + 1 ; end mend = getMemory(); end function [y,mstart,mend] = whileAllocate(x) mstart = getMemory(); n = numel(x) ; k = 1 ; y(1,n) = 0 ; while k <= n y(k) = burden(x(k)) ; k = k + 1 ; end mend = getMemory(); end