why is acumarray much slower calculating means than sum?

3 views (last 30 days)
Hi all,
why is acumarray much slower calculating means than sum?
I understand averages are slightly more complex, but I wouldn't expect 20x slower. Here's some code:
ind = randi([1,100],1000000,1);
dat = randn(1e6,1);
f_mean = @() accumarray(ind,dat,[],@mean);
f_sum = @() accumarray(ind,dat,[],@sum);
>> timeit(f_mean)
ans =
0.0562
>> timeit(f_sum)
ans =
0.0028
If I benchmark taking averages and sums using the following code, I get approximately only twice as slow using averages vs sum:
tic;
for jj = 1:1000
x = randn(100,1);
mean(x);
end
toc
Elapsed time is 0.005451 seconds.
tic;
for jj = 1:1000
x = randn(100,1);
sum(x);
end
toc
Elapsed time is 0.002414 seconds.
  2 Comments

Sign in to comment.

Accepted Answer

Bruno Luong
Bruno Luong on 9 Aug 2022
Edited: Bruno Luong on 9 Aug 2022
The default behavior of accumarray is sum and it's low-level coded.
When you pass user-defined function MATLAB will call the function and the overhead is significan't slower.
i=randi(10,1e6,1);
v=rand(size(i));
tic; accumarray(i,v); toc
Elapsed time is 0.008750 seconds.
tic; accumarray(i,v,[],@sum); toc % smart parsing
Elapsed time is 0.007060 seconds.
tic; accumarray(i,v,[],@(x) sum(x)); toc % % smart parsing stops here
Elapsed time is 0.090754 seconds.
The faster way to compute mean is
tic; meanv = accumarray(i,v)./accumarray(i,1); toc
Elapsed time is 0.007861 seconds.
tic; meanv = accumarray(i,v,[],@mean); toc
Elapsed time is 0.087376 seconds.

More Answers (1)

Matt J
Matt J on 9 Aug 2022
Edited: Matt J on 9 Aug 2022
I suspect it is because, when you pass in @sum, accumarray is smart enough to recognize that it can use its default settings, which are implemented in a less generic and well-optimized way.The timing comparisons below support this.
Note, in any case, that the speed differences have nothing to do with the complexities of the summation and mean operations themselves. When we specify summation using an anonymous function, we get the same slow speed as with @mean.
ind = randi([1,100],1000000,1);
dat = randn(1e6,1);
f_mean = @() accumarray(ind,dat,[],@mean);
f_sum = @() accumarray(ind,dat,[],@sum);
f_sumAnon = @() accumarray(ind,dat,[],@(x) sum(x));
f_sumDefault = @() accumarray(ind,dat);
timeit(f_mean)
ans = 0.0790
timeit(f_sumAnon)
ans = 0.0781
timeit(f_sumDefault)
ans = 0.0033
timeit(f_sum)
ans = 0.0033
  2 Comments

Sign in to comment.

Tags

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!