我做错了什么吗?还是标量乘向量真的很昂贵?MATLAB(ver2012a或更高版本(不是以某种方式优化代码以防止这种好奇心吗?
>> tic; for i=1:100000; x = sin(i)*[1; 1]; end; toc;
Elapsed time is 1.338225 seconds.
>> tic; for i=1:100000; x = sin(i).*[1; 1]; end; toc;
Elapsed time is 1.228331 seconds.
>> tic; for i=1:100000; x = [sin(i); sin(i)]; end; toc;
Elapsed time is 0.073888 seconds.
>> tic; for i=1:100000; tmp=sin(i); x = [tmp; tmp]; end; toc;
Elapsed time is 0.072120 seconds.
你能给我什么指导方针来让MATLAB中的FLOPS花费他们真正需要的时间。
PS。这只是一个示例代码,我所做的是解决ode系统,并且我想在计算所需的差分时优化运行时。以上的情况让我担心我可能会以一种非最佳的方式做一些事情。
"MATLAB(ver2012a或更高版本(不是以某种方式优化了代码吗防止这种好奇心?">
是的,如果代码位于函数m文件内,则会这样做,因为JIT编译器(实时编译器(和/或加速器
然而,正如评论和其他答案中所提到的,如果可能的话,矢量化通常仍然是更好的选择
直接命令行:
tic; for i=1:100000; x1 = sin(i)*[1; 1]; end; toc;
tic; for i=1:100000; x2 = sin(i).*[1; 1]; end; toc;
tic; for i=1:100000; x3 = [sin(i); sin(i)]; end; toc;
tic; for i=1:100000; tmp=sin(i); x4 = [tmp; tmp]; end; toc;
Elapsed time is 1.795528 seconds.
Elapsed time is 1.606081 seconds.
Elapsed time is 0.072672 seconds.
Elapsed time is 0.065904 seconds.
在一个函数内
[x1,x2,x3,x4]=foo();
Elapsed time is 0.029698 seconds.
Elapsed time is 0.035248 seconds.
Elapsed time is 0.064080 seconds.
Elapsed time is 0.054499 seconds.
函数foo保存为:
function [x1,x2,x3,x4]=foo()
tic; for i=1:100000; x1 = sin(i)*[1; 1]; end; toc;
tic; for i=1:100000; x2 = sin(i).*[1; 1]; end; toc;
tic; for i=1:100000; x3 = [sin(i); sin(i)]; end; toc;
tic; for i=1:100000; tmp=sin(i); x4 = [tmp; tmp]; end; toc;
end
编辑
当我试图找到支持上述声明的文档时,我意识到我犯了一个错误,它也加速了脚本m文件,因此函数在之上被编辑
在脚本中
fooscript;
Elapsed time is 0.033536 seconds.
Elapsed time is 0.033720 seconds.
Elapsed time is 0.066050 seconds.
Elapsed time is 0.058428 seconds.
脚本fooscript包含:
tic; for i=1:100000; x1 = sin(i)*[1; 1]; end; toc;
tic; for i=1:100000; x2 = sin(i).*[1; 1]; end; toc;
tic; for i=1:100000; x3 = [sin(i); sin(i)]; end; toc;
tic; for i=1:100000; tmp=sin(i); x4 = [tmp; tmp]; end; toc;
遗憾的是,没有大量关于JIT和加速器的文档(如果有的话(。但是,为了进行比较,您可以使用feature('accel','on'/'off')
和feature('jit','on'/'off')
禁用JIT或加速。(注意:禁用accel也会禁用jit,因为它似乎是accel的一部分。(
如果禁用accel,则性能提高会降低,但是函数和脚本性能仍然相似,并且仍然明显快于命令行。
禁用JIT对性能没有明显影响,因此原始语句是错误的。
你的for
循环正在杀死你的
这是你的代码在我的机器上的时间:
tic; for i=1:100000; x = sin(i)*[1; 1]; end; toc;
tic; for i=1:100000; x = sin(i).*[1; 1]; end; toc;
tic; for i=1:100000; x = [sin(i); sin(i)]; end; toc;
运行时间为0.799754秒
运行时间为0.819284秒
运行时间为1.90613秒
如果你把它矢量化,你就会得到
t=1:100000;
tic; t=1:100000; x = sin(t).'*[1; 1].'; toc;
tic; t=1:100000; sin(t).*[1;1] ; toc;
tic; t=1:100000; [sin(t);sin(t)] ; toc;
运行时间为0.015624秒
运行时间为0.0380838秒
运行时间为0.0322251秒
tmp=sin(i); x = [tmp; tmp];
与[sin(t);sin(t)];
相同
MATLAB针对涉及矩阵和向量的运算进行了优化。在许多情况下,您可以重写基于循环的、面向标量的代码,以使用MATLAB矩阵和矢量运算,这一过程称为矢量化。矢量化代码通常比包含循环的相应代码运行得更快。
例如:
>> tic; for i=1:100000; x = sin(i)*[1; 1]; end; toc;
Elapsed time is 2.859756 seconds.
使用矩阵运算可以执行相同的计算:
>> tic; x = [1;1]*sin(1:100000); toc
Elapsed time is 0.007731 seconds.