首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >递归循环优化

递归循环优化
EN

Stack Overflow用户
提问于 2013-05-31 00:12:36
回答 2查看 190关注 0票数 0

有没有办法重写我的代码,让它更快?

代码语言:javascript
运行
复制
for i = 2:length(ECG)
    u(i) = max([a*abs(ECG(i)) b*u(i-1)]);
end;

我的问题是心电图的长度。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-05-31 00:26:42

您应该像这样预先分配u

代码语言:javascript
运行
复制
>> u = zeros(size(ECG));

或者可能像这样

代码语言:javascript
运行
复制
>> u = NaN(size(ECG));

或者甚至像这样

代码语言:javascript
运行
复制
>> u = -Inf(size(ECG));

这取决于你想要的行为。

当您预先分配一个向量时,MATLAB知道该向量将有多大,并保留适当大小的内存块。

如果你不进行预分配,那么MATLAB就无法知道最终的向量会有多大。最初它会分配一个很短的内存块。如果该块中的空间用完了,那么它必须在某个地方找到更大的内存块,并将所有旧值复制到新的内存块中。每次分配的块中的空间耗尽时都会发生这种情况(并不是每次增加数组时都会发生这种情况,因为MATLAB运行时可能足够聪明,可以请求比所需的内存多一点的内存,但这仍然是必要的)。所有这些不必要的重新分配和复制都需要很长时间。

票数 2
EN

Stack Overflow用户

发布于 2013-05-31 01:50:13

有几种方法可以优化这个for循环,但令人惊讶的是,内存预分配并不是节省时间最多的部分。到目前为止。在每次迭代中,您都会构建此向量。使用max的双参数形式并传递两个标量要快得多:在我的机器上,对于大的ECG向量,速度要快得多!

代码语言:javascript
运行
复制
% Set the parameters and create a vector with million elements
a = 2;
b = 3;
n = 1e6;
ECG = randn(1,n);

ECG2 = a*abs(ECG); % This can be done outside the loop if you have the memory
u(1,n) = 0;        % Fast zero allocation
for i = 2:length(ECG)
    u(i) = max(ECG2(i),b*u(i-1)); % Compare two scalars
end

对于max的单输入表单(不包括随机ECG数据的创建):

代码语言:javascript
运行
复制
Elapsed time is 1.314308 seconds.

对于我上面的代码:

代码语言:javascript
运行
复制
Elapsed time is 0.017174 seconds.

仅供参考,上面的代码假定为u(1) = 0。如果这不是真的,那么u(1)应该在预分配之后设置为它的值。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16841080

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档