我做错了什么,或者逐个标量的乘法真的如此昂贵? MATLAB(2012版或更高版本)不是以某种方式优化代码以防止这种好奇心吗?
>> 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。这只是一个示例代码,我所做的是解决颂歌系统,我想在计算所需差异时优化运行时间。以上是让我担心我可能会以非最佳方式做某事。
答案 0 :(得分:3)
“MATLAB(2012版或更高版本)不以某种方式优化代码 防止这种好奇心?“
是的,如果代码在函数 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对性能没有明显影响,因此原始声明是错误的。
答案 1 :(得分:2)
你的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)];
答案 2 :(得分:0)
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.