access time of data in cell array vs matrix
Show older comments
Hello
I am doing operations (denoising/detection etc) on images and it seems that it is faster to store them in a cell array rather than a matrix to access them. It comes as a surpise to me. I give an exemple right under doing convolutions.
What is the reason for this ?
% create data
N_img = 1000;
img = rand(512,512,N_img);
for ii=size(img,3):-1:1
img_cell{ii}=img(:,:,ii);
end
% comparison on convolutions
tic
out_cell = img_cell;
for ii=1:N_img
out_cell{ii} = imgaussfilt(img_cell{ii});
end
toc
% I get 1.6s-1.8s
clear out_cell
tic
out_mat = img; %allocation inside or out of the timer does not change the trend
for ii=1:N_img
out_mat(:,:,ii) = imgaussfilt(img(:,:,ii));
end
toc
clear out_mat
% I get ~3.2 s
Sincerely,
1 Comment
I would take the imgaussfilt out of there to see the difference in access times more transparently:
% create data
N_img = 1000;
img = rand(512,512,N_img);
img_cell=num2cell(img,[1,2]);
tic
out_cell = img_cell;
for ii=1:N_img
out_cell{ii} = img_cell{ii};
end
toc
tic
out_mat = img;
for ii=1:N_img
out_mat(:,:,ii) = img(:,:,ii);
end
toc
Accepted Answer
More Answers (1)
Because extracting from cell arrays involves no new memory allocation. And because N_img=1000 is still very small.
8 Comments
Dyuman Joshi
on 19 Oct 2023
"Because extracting from cell arrays involves no new memory allocation."
Matt, could you provide a reference for this?
I wouldn't know where to find one at this moment, but it's easy to test with the code below. As you can see, accessing the cell results in no drop in available memory.
%%Array Access
clear
A=rand(512,512,512);
memory().MemAvailableAllArrays/2^30
B=A(:,:,:);
memory().MemAvailableAllArrays/2^30
ans =
16.7951
ans =
15.7946
%%Cell access
clear
C={rand(512,512,512)};
memory().MemAvailableAllArrays/2^30
D=C{1};
memory().MemAvailableAllArrays/2^30
ans =
16.7966
ans =
16.7966
Matt
on 19 Oct 2023
@Matt Yes, but allocating memory for processing output is not what differentiates the two implementations. Obviously, memory needs to be allocated to hold the output of the processing in both cases. However, you should be able to see from my test that, only in the case where you access with img(:,:,1) is new memory allocated for the input as well. A new block of memory is created to hold a copy of img(:,:,1), even before imgaussfilt or any other processing step is done.
Matt J
on 19 Oct 2023
As an additional test, look at the following which also shows memory consumption as tracked over time with the Windows Task Manager. With cell arrays, the memory spike is half the size.
clear
A=rand(512,512,512*3);
B=A(:,:,:);
sum(B(:));
clear

%%Cell access
clear
C={rand(512,512,512*3)};
D=C{1};
sum(D(:))
clear

Matt
on 20 Oct 2023
James Tursa
on 20 Oct 2023
Edited: James Tursa
on 20 Oct 2023
I doubt there is an official reference for this, but that is how it has always worked for cell and struct and property extraction. You get shallow copies (shared data or reference), not deep copies.
Walter Roberson
on 23 Oct 2023
Edited: Matt J
on 23 Oct 2023
https://www.mathworks.com/matlabcentral/answers/2035921-access-time-of-data-in-cell-array-vs-matrix#comment_2930491 shows it happening in practice, the same "pr"
This is an application of copy-on-write which is a fundamental MATLAB memory mechanism.
Categories
Find more on Data Type Identification in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!