有没有办法重写我的代码以使其更快?
for i = 2:length(ECG)
u(i) = max([a*abs(ECG(i)) b*u(i-1)]);
end;
我的问题是心电图的长度。
有没有办法重写我的代码以使其更快?
for i = 2:length(ECG)
u(i) = max([a*abs(ECG(i)) b*u(i-1)]);
end;
我的问题是心电图的长度。
u
你应该像这样预先分配
>> u = zeros(size(ECG));
或者可能像这样
>> u = NaN(size(ECG));
或者甚至可能像这样
>> u = -Inf(size(ECG));
取决于你想要什么行为。
当您预先分配一个向量时,MATLAB 知道该向量将有多大并保留一个适当大小的内存块。
如果您不预先分配,那么 MATLAB 将无法知道最终向量的大小。最初它将分配一小块内存。如果该块中的空间不足,则它必须在某处找到更大的内存块,并将所有旧值复制到新内存块中。每次分配块中的空间不足时都会发生这种情况(可能不是每次增加数组时,因为 MATLAB 运行时可能足够聪明,可以要求比它需要的更多的内存,但它仍然超过必要的)。所有这些不必要的重新分配和复制都需要很长时间。
有几种方法可以优化这个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) 应该在预分配后设置为它的值。