MATLAB: Inefficient or slow use of colon-operator within a matrix

:array dimensioncolon

Dear all,
I'm struggling with the performance of my code for a while. I just found out the big issue.
It appeared that the use of colon-operator within a matrix (to include all subscripts in a particular array dimension) is incredibly slow or inefficient:
Data = ones(500,500,500);
clear Data2 Data3;
Data2 = Data;
toc; %--> Elapsed time is 0.006142 seconds.
Data3 = Data(:,:,:,1);
toc; %--> Elapsed time is 0.430237 seconds.
Why is the use of ":" / Colons 70 times (!!) slower. Is there a solution to give this a boost? I need the flexibility of "Data(:,:,:,d)" since in some cases my data is multidimensional.
Many thanks in advance. Looking forward to your response.

Best Answer

  • Yes, as Stephen says your comparison is not valid. In particular, due to the copy-on-write nature of matlab the two operations are completely different.
    Data2 = Data;
    In the background, all that does is create a new variable Data2 and tells it to find the content of the variable where Data is stored. There is no copying occuring (yet).
    Data3 = Data(:, :, :, 1);
    Creates a new variable Data3 (same step as before). But now, since you're taking a slice of Data, matlab can't just tell it to find its content where Data is stored. Instead it now has to copy that slice into a new memory address. That takes time.
    Now after that, if you did:
    Data3(1) = 2;
    That would be pretty much instant. Data3 is the only one pointing to its chunk of memory since data copy has already occured. Hence changing one value in that memory is quicky
    Data2(1) = 2;
    Now since Data2 and Data share the same memory, before matlab can change that Data2 value it must first copy the whole array into a new memory location, so Data2 and Data don't share it. That single line is going to take time to make it on par with your slice operation
    >> tic; Data2(1) = 2; toc
    Elapsed time is 0.478432 seconds.
    >> tic;Data3(1) = 2; toc
    Elapsed time is 0.000584 seconds.