0

有没有办法重写我的代码以使其更快?

for i = 2:length(ECG)
    u(i) = max([a*abs(ECG(i)) b*u(i-1)]);
end;

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

4

2 回答 2

2

u你应该像这样预先分配

>> u = zeros(size(ECG));

或者可能像这样

>> u = NaN(size(ECG));

或者甚至可能像这样

>> u = -Inf(size(ECG));

取决于你想要什么行为。

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

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

于 2013-05-30T16:26:42.377 回答
2

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

% 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数据):

Elapsed time is 1.314308 seconds.

对于我上面的代码:

Elapsed time is 0.017174 seconds.

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

于 2013-05-30T17:50:13.350 回答