如何使这段代码更有效率?

时间:2012-10-22 13:52:15

标签: performance matlab time for-loop

这是Profiler报告的一部分,显示了这些行如何耗费时间。可以改进吗?

         434 %clean up empty cells in subPoly
         228  435 if ~isempty(subPoly) 
         169  436     subPoly(cellfun(@isempty,subPoly)) = []; 
              437 
              438     %remove determined subpoly points from the hull polygon
         169  439     removeIndex = zeros(size(extendedPoly,1),1); 
         169  440     for i=1:length(subPoly) 
         376  441         for j=1:size(subPoly{i}(:,1)) 
       20515  442             for k=1:size(extendedPoly,1) 
6.12 5644644  443                 if extendedPoly(k,:)==subPoly{i}(j,:) 
       30647  444                     removeIndex(k,1)=1; 
       30647  445                 end 
1.08 5644644  446             end 
0.02   20515  447         end 
         376  448     end 
         169  449     extendedPoly = extendedPoly(~removeIndex(:,1),:);  
         169  450 end 

2 个答案:

答案 0 :(得分:2)

由于Matlab倾向于认为命令行上的所有内容都是双精度数组,并且假设数组和单元格数组的内容是数字,您可以替换

         if extendedPoly(k,:)==subPoly{i}(j,:) 
             removeIndex(k,1)=1; 
         end 

与等效

removeIndex(k,1) = extendedPoly(k,:)==subPoly{i}(j,:)

可能会节省几纳秒,但如果能节省更多,我会感到有些惊讶。

我怀疑如果我更聪明或更勤奋,我可以用

的单一作业替换你的整个循环巢。
removeIndex = extendedPoly==subPoly

这里的技巧是确保表达式中的所有数组都具有相同的尺寸。

答案 1 :(得分:1)

您可能正在接近当前嵌套策略中的性能限制。 “慢”行每次执行只需要1个usec。

通常在这样的集合匹配情况下,最好对两个集合进行排序,然后同时在两个集合中执行单个循环。 (Google“插入排序”了解更多信息,另请参阅此相关问题/答案Optimization of timestamp filter in MATLAB - Working with very large datasets

如何最好地将此应用于您的环境并不是很明显。如果您发布可执行示例,我们可以更密切地研究这个问题。

在不查看可执行代码的情况下,将矢量的subPoly单元扩展为单个排序数字数组(称为sortedElementsToremove之类的内容)可能是有意义的。然后从extendedPoly获取排序顺序,如下所示:[~, ixsSortExpended] = sort(extendedPoly);

现在,您可以使用具有两个索引的单个循环来执行屏蔽。这样的事情(未经过测试的代码):

ixExtended = 1;  %Index though sort order
for ixSub = 1:length(sortedElementsToremove);
    %Use while to update second index
    while ...
            (extendedPoly(ixsSortExpended(ixExtended))  < sortedElementsToremove(ixSub) ) && ...
            ixExtended < length(ixsSortExpended)
        ixExtended = ixExtended + 1;
    end
    if (sortedElementsToremove(ixSub) == extendedPoly(ixsSortExpended(ixExtended)))
        removeIndex(ixsSortExpended(ixExtended)) = true;
    end
end