这一观察并不重要,因为浪费在循环语句上的时间性能可能远高于循环本身。但无论如何,我会分享它,因为我搜索并找不到关于此的话题。我总是有这样的印象:预先分配我将循环的数组,然后循环它,将比直接循环它更好,并决定检查它。代码是比较这两个人之间的效率:
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
但我得到的结果是:
Pure for with column on statement:
Elapsed time is 0.003309 seconds.
Pure for with column declared before statement:
Elapsed time is 0.208744 seconds.
为什么会这样?不应该预先分配更快?
事实上,matlab help for
说:
当出现冒号表达式时,长循环的内存效率更高 因为从不创建索引向量,所以在FOR语句中。
所以,与我的期望相矛盾 for语句中的列表达式更好,因为它没有分配向量,因此更快。
我制作了以下脚本来测试其他场合我也认为会更快:
% 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
时间安排如下:
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.
结论:
但我无法回答的问题是,细胞怎么样,为什么没有时差?开销可能远低于观察到的开销?或者它必须分配单元格,因为它不是基本类型的双重?
如果您知道有关此主题的其他技巧,请填写。
只需在@Magla的回答中添加时间以显示转动feature('accel','off')
的结果。
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.
结果现在按预期区域......
答案 0 :(得分:3)
这个发现与预分配无关:它处理matlab是否启用计算具有多个核心的东西。在for
语句中插入冒号运算符时,它会告诉matlab使用多个核(即多线程)。
如果仅使用feature('accel','off')
在一个核心上设置matlab,则观察到的与doubles
的差异消失。关于cells
,matlab没有使用多线程 - 因此无法观察到任何差异(无论accel
的状态如何)。
使用冒号时,for
循环是多线程的,并且只有在使用冒号时才会出现多线程。以下类似长度的向量不会涉及多个核心:
for k = randperm(N)
for k = linspace(1,N,N)
但是for k = 1:0.9999:N
是多线程的。
可以在matlab's support page找到一个解释。它指出,当“函数执行的算法中的操作很容易划分为可以同时执行的部分时,可以完成多核处理。”使用冒号运算符,Matlab知道可以对for
进行分区。