why is acumarray much slower calculating means than sum?
Mostrar comentarios más antiguos
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 comentarios
You are right, it is slower by a fair bit.
ind = randi([1,100],1000000,1);
dat = randn(1e6,1);
f_mean = @() accumarray(ind,dat,[],@mean);
f_sum = @() accumarray(ind,dat,[],@sum);
N = 50;
tm = zeros(N,1); ts = zeros(N,1);
for K = 1 : N; t0 = tic; f_mean(); tend = toc(t0); tm(K) = tend; end
for K = 1 : N; t0 = tic; f_sum(); tend = toc(t0); ts(K) = tend; end
plot([tm, ts]);
legend({'mean', 'sum'})
mean(tm) ./ mean(ts)
dleal
el 9 de Ag. de 2022
Respuesta aceptada
Más respuestas (1)
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)
timeit(f_sumAnon)
timeit(f_sumDefault)
timeit(f_sum)
2 comentarios
If you wish to do a more optimized group-wise mean, you can implement it this way:
ind = randi([1,100],1000000,1);
dat = randn(1e6,1);
f_mean = @() accumarray(ind,dat)./accumarray(ind,1);
timeit(f_mean)
dleal
el 9 de Ag. de 2022
Categorías
Más información sobre Creating and Concatenating Matrices en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
