本文介绍了循环语句的性能并预先分配循环语句本身的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

这个观察并不重要,因为循环语句浪费的时间性能可能比循环本身高得多。但无论如何,我会分享它,因为我搜索,找不到这个话题。我总是有这样的印象,预先分配我会循环的数组,然后循环,将比直接循环,并决定检查它。代码是比较这两个函数之间的效率:

$ $ p $ $ $ $ c $ disp('Pure for with column on statement:')
tic
for k = 1:N
end
toc

disp('Pure for with column declared before statement:')
tic
M = 1:N;
for k = m
end
toc

但结果我得到的是:

 对于在列上声明的纯
经过的时间为0.003309秒。
声明之前声明为列的纯粹
经过的时间为0.208744秒。

为什么这是那个?不应该预先分配更快?



事实上,的matlab 帮助说:

So, contradicting my expectations the column expression at the for statement is better, because it does not allocate the vector and, because of that, is faster.

I made the following script to test other occasions that I also would think that would be faster:

% For comparison:
N=1000000;

disp('Pure for loop on cell declared on statement:')
tic
for k=repmat({1},1,N)
end
toc

disp('Pure for loop on cell declared before statement:')
tic
mcell=repmat({1},1,N);
for k=mcell
end
toc

disp('Pure for loop calculating length on statement:')
tic
for k=1:length(mcell)
end
toc

disp('Pure for loop calculating length before statement:')
tic
lMcell = length(mcell);
for k=1:lMcell
end
toc

disp('Pure while loop using le:')
% While comparison:
tic
k=1;
while (k<=N)
  k=k+1;
end
toc

disp('Pure while loop using lt+1:')
% While comparison:
tic
k=1;
while (k<N+1)
  k=k+1;
end
toc


disp('Pure while loop using lt+1 pre allocated:')
tic
k=1;
myComp = N+1;
while (k<myComp)
  k=k+1;
end
toc

And the timings are:

Pure for loop on cell declared on statement:
Elapsed time is 0.259250 seconds.
Pure for loop on cell declared before statement:
Elapsed time is 0.260368 seconds.
Pure for loop calculating length on statement:
Elapsed time is 0.012132 seconds.
Pure for loop calculating length before statement:
Elapsed time is 0.003027 seconds.
Pure while loop using le:
Elapsed time is 0.005679 seconds.
Pure while loop using lt+1:
Elapsed time is 0.006433 seconds.
Pure while loop using lt+1 pre allocated:
Elapsed time is 0.005664 seconds.

Conclusions:

  • You can gain a bit of performance just by loop on comma statements, but that can be negligible comparing to the time spent on the for-loop.
  • For cells the difference seems to be negligible.
  • It is better to pre-allocate length before doing the loop.
  • The while has the same efficiency as the for without pre-allocating the vector, which makes sense as stated before
  • As expected, it is better to calculate fixed expressions before the while statement.

But the question that I can't answer is, what about the cell, why isn't there time difference? The overhead could be much lesser than the observed? Or it has to allocate the cells since it is not a basic type as a double?

If you know other tricks concerning this topic fill free to add.


Just adding the timings to show the results of turning feature('accel','off') as said in @Magla's answer.

Pure for with column on statement:
Elapsed time is 0.181592 seconds.
Pure for with column declared before statement:
Elapsed time is 0.180011 seconds.
Pure for loop on cell declared on statement:
Elapsed time is 0.242995 seconds.
Pure for loop on cell declared before statement:
Elapsed time is 0.228705 seconds.
Pure for loop calculating length on statement:
Elapsed time is 0.178931 seconds.
Pure for loop calculating length before statement:
Elapsed time is 0.178486 seconds.
Pure while loop using le:
Elapsed time is 1.138081 seconds.
Pure while loop using lt+1:
Elapsed time is 1.241420 seconds.
Pure while loop using lt+1 pre allocated:
Elapsed time is 1.162546 seconds.

The results now area as expected…

解决方案

This finding has nothing to do with preallocating or not: it deals with matlab being enable or not to compute things with several cores. When you insert the colon operator within the for statement, it tells matlab to use several cores (i.e. multithreading).

If you set matlab on one core only with feature('accel','off'), the observed difference with doubles vanishes. Concerning cells, matlab does not make use of multithreading - therefore no difference can be observed (whatever the status of accel is).

The for loop is multithreaded when a colon is used, and only if a colon is used. The following vectors of similar length does not engage several cores:

  • for k = randperm(N)
  • for k = linspace(1,N,N)

but for k = 1:0.9999:N is multithreaded.

One explanation can be found on this matlab's support page. It states that multi-core processing can be done when "The operations in the algorithm carried out by the function are easily partitioned into sections that can be executed concurrently.". With a colon operator, Matlab knows that for can be partitioned.

这篇关于循环语句的性能并预先分配循环语句本身的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-08 21:01