Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

"cellfun" Is Slower Than "for" Loop

201 views
Skip to first unread message

Royi Avital

unread,
Jan 28, 2011, 5:52:03 AM1/28/11
to
Hello.

Tried to understand what's better to do when I want to apply the same operation on matrices within a cell.

Used the following script:

%% cellfun Vs. for loop
clear all
% Creating the Data Set
C = cell(1000, 1);
for i = 1:1000
C{i} = randn(500);
end

% Function Handle for the cellfun operation
fun = @(x) x .* 5;

tic
cellfun(fun, C, 'UniformOutput', false);
toc

tic
for i = 1:1000
5 * C{i};
end
toc

Results:
Elapsed time is 1.598640 seconds.
Elapsed time is 0.861648 seconds.

Looping through the cell is faster by a factor of 2.
How could that be?
What's the point with "cellfun" if that's the case?

For instance, bsxfun is much faster then looping.

Jan Simon

unread,
Jan 28, 2011, 7:23:04 AM1/28/11
to
Dear Royi,

I cannot confirm your measurement under Matlab 2009a.
I've move the code insider a function to allow Matlab's JIT acceleration to work like in a real program.

function CellTest


C = cell(1000, 1);
for i = 1:1000

C{i} = rand(100); % Avoid disk swapping
end

fun = @(x) x .* 5;
tic

C2 = cellfun(fun, C, 'UniformOutput', false);
toc
% 0.276 sec

clear C2
tic
C2 = cellfun(@(x) x .* 5, C, 'UniformOutput', false);
toc
% 0.278 sec

clear C2
tic
C2 = cellfun(@times5, C, 'UniformOutput', false);
toc
% 0.274 sec

C2 = cell(1000, 1);


tic
for i = 1:1000

C2{i} = 5 * C{i};
end
toc
% 0.302

function A = times5(A)
A = A .* 5;

I assume that either some disk swapping due to a full memory or a speedstepping of your processor caused your measurements. Running code in the command line or in a script can influence the speed also compared with running a function.

Kind regards, Jan

Bruno Luong

unread,
Jan 28, 2011, 7:52:03 AM1/28/11
to
"Royi Avital" wrote in message <ihu74j$rnl$1...@fred.mathworks.com>...

>
> Looping through the cell is faster by a factor of 2.
> How could that be?
> What's the point with "cellfun" if that's the case?

It's a well known fact. Advantage: Shorter syntax and only faster for built-in function. There is a lenghtly thread on this discussion on the pass.

Bruno

Royi Avital

unread,
Jan 28, 2011, 8:06:04 AM1/28/11
to
"Bruno Luong" <b.l...@fogale.findmycountry> wrote in message <ihue5j$5l$1...@fred.mathworks.com>...

Could you kink me to the thread?
You say cellfun is only faster when using the built in anonymous functions of MATLAB?

Thanks.

Bruno Luong

unread,
Jan 28, 2011, 8:13:03 AM1/28/11
to

> Could you kink me to the thread?

http://www.mathworks.com/matlabcentral/newsreader/view_thread/253815
http://www.mathworks.com/matlabcentral/newsreader/view_thread/253596
http://www.mathworks.com/matlabcentral/newsreader/view_thread/251700
http://blogs.mathworks.com/loren/2009/05/05/nice-way-to-set-function-defaults/

> You say cellfun is only faster when using the built in anonymous functions of MATLAB?

Not anonymous functions, some builtin functions such as size, length, numel, isempty ... when called with a string syntax. Check the doc and the above threads.

Bruno

Matt J

unread,
Jan 28, 2011, 9:09:04 AM1/28/11
to
"Royi Avital" wrote in message <ihu74j$rnl$1...@fred.mathworks.com>...
>
> tic
> cellfun(fun, C, 'UniformOutput', false);
> toc
>
> tic
> for i = 1:1000
> 5 * C{i};
> end
> toc
============

This isn't really a fair test. Firstly, your call to cellfun allocates memory for a whole new cell array of size(C). Conversely, your for-loop simply discards the result of 5*C{i} with each pass through the loop. Secondly, your call to cellfun must process the anonymous function, whereas in your for-loop, the operation 5*x is hard-coded.

With my modified version of your test below, I get much more comparable behavior between cellfun and the for-loop.


% Creating the Data Set

n=500;
C = cell(n, 1);
for i = 1:n
C{i} = randn(200);
end

% Function Handle for the cellfun operation
fun = @(x) x .* 5;

tic
cellfun(fun, C, 'UniformOutput', false);
toc

%Elapsed time is 0.132369 seconds.

tic
D=C;
for i = 1:n
D{i} = 5 * C{i};
end
toc
%Elapsed time is 0.129305 seconds.

tic
D=C;
for i = 1:n
D{i} = fun( C{i} );
end
toc
%Elapsed time is 0.161916 seconds.

0 new messages