在Matlab中如何提高运行时效率?

3

我有一些代码运行时间很长(几个小时),我认为是因为在if语句中进行了大量比较。我希望它能更快地运行,有没有什么有用的建议可以改善运行时间?如果有人对代码运行变慢的原因有不同的想法,我会非常感激。

xPI = zeros(1,1783);
argList2 = zeros(1,1783);
aspList2 = zeros(1,1783);
cysList2 = zeros(1,1783);
gluList2 = zeros(1,1783);
hisList2 = zeros(1,1783);
lysList2 = zeros(1,1783);
tyrList2 = zeros(1,1783);

minList= xlsread('20110627.xls','CM19:CM25');
maxList= xlsread('20110627.xls','CN19:CN25');
N = length(pIList);
for i = 1:N
    if (argList(i)>= minList(1) && argList(i) <= maxList(1)) ...
        && (aspList(i)>= minList(2) && aspList(i) <= maxList(2)) ...
        && (cysList(i)>= minList(3) && cysList(i) <= maxList(3)) ...
        && (gluList(i)>= minList(4) && gluList(i) <= maxList(4)) ...
        && (hisList(i)>= minList(5) && hisList(i) <= maxList(5)) ...
        && (lysList(i)>= minList(6) && lysList(i) <= maxList(6)) ...
        && (tyrList(i)>= minList(7) && tyrList(i) <= maxList(7))

        xPI(i) = pIList(i);
        argList2(i) = argList(i);
        aspList2(i) = aspList(i);
        cysList2(i) = cysList(i);
        gluList2(i) = gluList(i);
        hisList2(i) = hisList(i);
        lysList2(i) = lysList(i);
        tyrList2(i) = tyrList(i);
        disp('passed test');
    end
end
2个回答

7
你可以尝试矢量化代码;我已经准备了一些示例数据集,并复制了你在下面执行的一些操作。
matA1 = floor(rand(10)*1000); 
matB1 = floor(rand(10)*1000);

matA2 = zeros(10); 
matB2 = zeros(10);

minList = [10, 20]; 
maxList = [100, 200];

indicesToCopy = ( matA1 >= minList(1) ) & ( matA1 <= maxList(1) ) & ( matB1 >= minList(2) ) & ( matB1 <= maxList(2) );

matA2(indicesToCopy) = matA1(indicesToCopy); 
matB2(indicesToCopy) = matB1(indicesToCopy);

不知道这是否更快,你需要试一下。

编辑:
由于只进行了两次调用,所以这并不太重要,但是xlsread非常慢。您可以通过使用该函数的变体语法来加速这些调用。

num = xlsread(filename, sheet, 'range', 'basic')

问题在于range参数被忽略,整个表格都会被读取,因此你需要正确地处理索引来得到想要的结果。


2
要创建indicesToCopy数组,您需要使用&逐元素逻辑与,而不是&&短路逻辑与。 - Lambdageek
2
+1,我敢打赌100个声望值,它会快很多。(只是在谈论循环)。 - Chris A.
我刚刚尝试了你的建议,大大地将运行时间从几个小时缩短到了几分钟! - Ben Fossen
@Lambdageek:谢谢,最后我只是复制粘贴了那个语法错误的行 :) - Praetorian
3
Ben,正如Doc. Brown所说,“你没有考虑到第四个维度!”尽可能避免在Matlab中使用for循环,它是为处理高维数据而构建的 :) - Yanir Kleiman

6
使用分析器查看哪些行或函数使用了最多的执行时间。
通过向量化代码,您可能可以大幅提高执行速度。这意味着使用一次操作即可对整个向量进行操作,而不是使用for循环来迭代它。例如:
% make a logical vector indicating what you want to include
ii = (argList >= minList(1) & argList  <= maxList(1)) & ...

% use it
argList2(ii) = arglist(ii); % copies over every element where the corresponding ii is 1
...

1
分析器是找出哪里需要优化的正确工具,但在这里,运行时间可能不会被任何单独一行支配。相反,整个代码块都是一个需要向量化的“优化单元”。如果没有人事先了解过向量化的话,我认为这在分析器结果中并不明显。 - nibot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接