report a MATLAB problem (calling cell as {A{i}} being faster than A(I))

1 回表示 (過去 30 日間)
mostafa
mostafa 2017 年 9 月 7 日
編集済み: mostafa 2017 年 9 月 8 日
MATLAB says that "{A{I}} can usually be replaced by A(I) or A(I)', which can be much faster."
but you can see in the following example that it's 5 times slower!
%----------- example ----------------
a = randi(255,100,100,100);
[s1,s2,s3] = size(a);
a2 = cell(s3);
for k=1:s3
a2{k} = a(:,:,k);
end
%--------------- (1) faster ------------
tic
for t = 1:1
for i = 1:s1
for j=1:s2
for k=1:s3
b = {a2{k}};
end
end
end
end
toc
%---------------- (2) slower -----------
tic
for t = 1:1
for i = 1:s1
for j=1:s2
for k=1:s3
b = a2(k);
end
end
end
end
toc
%---- Result --------
Elapsed time is 1.188993 seconds.
Elapsed time is 5.511241 seconds.

採用された回答

Guillaume
Guillaume 2017 年 9 月 7 日
That is indeed strange.
Note that A(k) makes a lot more sense than {A{k}}. Both create the same thing but conceptually, A(k) just says give the cell at index k whereas {A{k}} says give me the content of the cell at index k and put it into a cell again.
Behind the scenes, both syntaxes have to allocate memory for a 1x1 cell array and then copy the pointer to the matrix contained in the cell, so I don't understand why the massive difference in speed. Only Mathworks can tell us what is actually happening.
At the end of the day, unless the profiler has highlighted that line as a bottleneck, I would go with the A(k) syntax which in my opinion is more appropriate and easier to read.
Note that if you're chasing for performance improvements, your example has two problems that have a lot more impact on speed and memory
  • the allocation of a 100x100 cell array, of which you only use the first column
a2 = cell(s3, 1); %allocate a 100x1 cell array instead of a 100x100 cell array
would be a lot better
  • the copying in a loop of the matrices
a2 = reshape(num2cell(a, [1 2]), [], 1); %num2cell will create a 1x1x100 vector cell array, then reshaped into a column vector.
would eliminate the loop and the need for the preallocation.
  3 件のコメント
mostafa
mostafa 2017 年 9 月 8 日
Dear Guillaume, thanks a lot for your helpful suggestions. I will use them.
mostafa
mostafa 2017 年 9 月 8 日
編集済み: mostafa 2017 年 9 月 8 日
Dear Stephen. You're right. I test this on MATLAB 2010a(64 bit) instead 2015b (32 bit). and see the following results.
%MATLAB 2010.a (64 bit)
% for "{A{k}}"
Elapsed time is 0.717778 seconds.
%for "A(k)"
Elapsed time is 0.640464 seconds.
compare to
% MATLAB 2015b (32 bit).
% for "{A{k}}"
Elapsed time is 1.222309 seconds.
%for "A(k)"
Elapsed time is 5.498703 seconds.
Thanks a lot for your answer.
I will use MATLAB 2010a. Till I can update MATLAB 2015 to a 64-bit version. and test more.
Also, I saw another important difference.
see the below example
function test_spend_time
%------------------------- (1) ----------------
tic
for i = 1:1e6
myfun1;
end
result1 = toc;
%------------------------- (2) ----------------
%---------------------- 2-1 ------
tic
for i = 1:1e6
myfun2;
end
result2_1 = toc;
%---------------------- 2-2 ------
tic
for i = 1:1e6
[~] = myfun2;
end
result2_2 = toc;
%---------------------- 2-3 ------ %fastest in 2015b.(32bit)
tic
for i = 1:1e6
[b] = myfun2;
end
result2_3 = toc;
%------------------------- (3) ----------------
tic
for i = 1:1e6
myfun3
end
result3 = toc;
fprintf('Elapsed time (1) \t=\t%g \n',result1)
fprintf('Elapsed time (2_1)\t=\t%g \n',result2_1)
fprintf('Elapsed time (2_2)\t=\t%g \n',result2_2)
fprintf('Elapsed time (2_3)\t=\t%g \n',result2_3)
fprintf('Elapsed time (3) \t=\t%g \n',result3)
% -------------------------------------------- %
function myfun1
result = [];
end
% -------------------------------------------- %
function result = myfun2
result = [];
end
% -------------------------------------------- %
function result = myfun3
end
end
results
% MATLAB 2010.a (64 bit)
Elapsed time (1) = 2.99033
Elapsed time (2_1) = 3.11761
Elapsed time (2_2) = 3.44073
Elapsed time (2_3) = 3.18837
Elapsed time (3) = 2.606
compare to 2015.b
% MATLAB 2015b (32 bit).
Elapsed time (1) = 2.72881
Elapsed time (2_1) = 4.98151
Elapsed time (2_2) = 4.47168
Elapsed time (2_3) = 0.151765 %fastest
Elapsed time (3) = 1.52223
I inspected these codes because my program has more than 20000 times of the calling similar of above codes. And these different times being very important.
At last, I hope these results be helpful for others and if possible tell to Mathworks team.
My English does not good. excuse me for any mistakes.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeWhos についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by