我正在努力提高我试图运行的脚本的速度。
这是代码:(我的机器= 4核心胜利7)
clear y;
n=100;
x=linspace(0,1,n);
% no y pre-allocation using zeros
start_time=tic;
for k=1:n,
y(k) = (1-(3/5)*x(k)+(3/20)*x(k)^2 -(x(k)^3/60)) / (1+(2/5)*x(k)-(1/20)*x(k)^2);
end
elapsed_time1 = toc(start_time);
fprintf('Computational time for serialized solution: %f\n',elapsed_time1);
上面的代码给出了0.013654的经过时间。
另一方面,我试图通过在上面的代码中添加y = zeros(1,n);
来使用预分配,其中注释是,但运行时间类似于~0.01左右。有什么想法吗?有人告诉我它会提高2倍。我错过了什么吗?
最后在Matlab中是否有任何类型的矢量化可以让我忘记上面代码中的for循环?
谢谢,
答案 0 :(得分:3)
在您的代码中:尝试使用n=10000
,您会看到更多差异(我的机器上差不多10倍)。
当变量的大小很大时,与分配相关的这些事情最为明显。在这种情况下,Matlab更难为该变量动态分配内存。
减少操作次数:进行矢量化,并重用中间结果以避免权限:
y = (1 + x.*(-3/5 + x.*(3/20 - x/60))) ./ (1 + x.*(2/5 - x/20));
<强>基准强>:
使用n=100
:
Parag / venergiac的解决方案:
>> tic
for count = 1:100
y=(1-(3/5)*x+(3/20)*x.^2 -(x.^3/60))./(1+(2/5)*x-(1/20)*x.^2);
end
toc
Elapsed time is 0.010769 seconds.
我的解决方案:
>> tic
for count = 1:100
y = (1 + x.*(-3/5 + x.*(3/20 - x/60))) ./ (1 + x.*(2/5 - x/20));
end
toc
Elapsed time is 0.006186 seconds.
答案 1 :(得分:2)
您不需要for
循环。用以下代替for
循环,MATLAB将处理它。
y=(1-(3/5)*x+(3/20)*x.^2 -(x.^3/60))./(1+(2/5)*x-(1/20)*x.^2);
当向量变得更大时,这可以提供计算优势。较小的尺寸是您无法看到预分配效果的原因。请阅读this页面,了解有关如何改善效果的其他提示。
编辑:我观察到,在较大的尺寸n>=10^6
时,当我尝试以下操作时,我的性能会不断提高:
x=0:1/n:1;
而不是使用linspace
。在n=10^7
,我使用linspace
获得0.05秒(0.03 vs 0.08)。
答案 2 :(得分:1)
尝试每个元素的操作元素(.*
,.^
)
clear y;
n=50000;
x=linspace(0,1,n);
% no y pre-allocation using zeros
start_time=tic;
for k=1:n,
y(k) = (1-(3/5)*x(k)+(3/20)*x(k)^2 -(x(k)^3/60)) / (1+(2/5)*x(k)-(1/20)*x(k)^2);
end
elapsed_time1 = toc(start_time);
fprintf('Computational time for serialized solution: %f\n',elapsed_time1);
start_time=tic;
y = (1-(3/5)*x+(3/20)*x.^2 -(x.^3/60)) / (1+(2/5)*x-(1/20)*x.^2);
elapsed_time1 = toc(start_time);
fprintf('Computational time for product solution: %f\n',elapsed_time1);
我的数据
序列化解决方案的计算时间:2.578290
序列化解决方案的计算时间:0.010060