在MATLAB中采用早期纾困

时间:2015-01-30 16:50:26

标签: performance matlab

本书中有一个Employ early bail-out示例(http://www.amazon.com/Accelerating-MATLAB-Performance-speed-programs/dp/1482211297)(@ YairAltman)。为了提高速度,我们可以转换此代码:

data = [];
newData = [];
outerIdx = 1;
while outerIdx <= 20
    outerIdx = outerIdx + 1;
    for innerIdx = -100 : 100
        if innerIdx == 0
            continue % skips to next innerIdx (=1)
        elseif outerIdx > 15
            break % skips to next outerIdx
        else
            data(end+1) = outerIdx/innerIdx;
            newData(end+1) = process(data);
        end
    end % for innerIdx
end % while outerIdx

到此代码:

function bailableProcessing()
for outerIdx = 1 : 5
    middleIdx = 10
    while middleIdx <= 20
        middleIdx = middleIdx + 1;
        for innerIdx = -100 : 100
            data = outerIdx/innerIdx + middleIdx;
            if data == SOME_VALUE
                return
            else
                process(data);
            end
        end % for innerIdx
    end % while middleIdx
end % for outerIdx
end % bailableProcessing()

我们如何进行此次转化?为什么我们在新代码中有不同的middleIdx范围?在新代码中检查innerIdxouterIdx的位置是什么?这个新的data = outerIdx/innerIdx + middleIdx计算是什么?

我们只有第二个代码的信息:

  

我们可以放置应该保存的代码段   专用功能和拯救时功能返回   情况发生。

2 个答案:

答案 0 :(得分:1)

它比你想象的要简单得多!

  

我们如何进行此转化?

无理性。这两个代码完全不同

  

为什么我们在新代码中有不同的middleIdx范围?

随机性。作者的观点是不同的。

  

在新代码中检查innerIdx和outerIdx的位置在哪里?

不需要,因为它不是相同的代码。

  

这个新数据是什么= outerIdx / innerIdx + middleIdx计算?

随机计算以及原始代码中的data(end+1) = outerIdx/innerIdx;

我想作者想要更深刻地说明一些事情:如果你在函数中包装你的代码(可能很多)循环(fors / whiles,无关紧要)并且你发出一个返回语句如果您以某种方式检测到您已完成,则会产生有效的&#34; bailable&#34;计算,例如工作的方法比通常更早返回。这里通过检查data == SOME_VALUE的条件来说明;你可以在那里找到你最喜欢的救助条件: - )

此外,第一个示例中的关键字[continue / break]旨在说明您可以[跳过其余的/离开]来自您调用它们的最内层循环。原则上,您可以通过例如

来实施救助
bailing = false;
for outer = 1:1000
   for inner = 1:1000
      if <somebailingcondition>
         bailing = true;
         break;
      else
         <do stuff>
      end
   end
   if bailing
     break;
   end
end

但这会非常笨拙,因为&#34;级联&#34;只要你有嵌套循环并弄乱代码,就需要中断。

我希望这可以澄清你的问题。

答案 1 :(得分:1)

对不起,我没有在文中澄清第二个代码段不是第一个代码段的直接替代品。如果你重读早期纾困部分(3.1.3),也许你会发现它有两个主要部分:

该部分的第一部分(包括顶部代码段)说明了使用break/continue从复杂处理循环中纾困的基本机制,以便节省计算值的处理时间不需要。

相反,本节的第二部分讨论了我们希望打破不是直接父循环的祖先循环的情况。我在文中提到在这种情况下我们可以使用三种替代方案,而你提到的第二个代码段就是其中之一(其他选择是使用break/continue的专用标志并使用{{ 1}}块)。我在该部分的第二部分中提供的三个代码段应该彼此相同,但它们不等同于该部分顶部的代码段。

也许我应该在文中澄清这一点,或者我应该在整个过程中使用相同的例子。我将在本书的第二版中考虑这个问题(如果出现的话)。

我在本书的其他部分使用了这些代码段的变体来说明性能加速的各种其他方面(例如,3.1.4和3.1.6) - 在所有这些情况下,代码段不等效对彼此。它们仅用于说明相应的文字。

我希望你喜欢我的书,并认为它很有用。如果您能在亚马逊(direct link)上发表积极反馈,我将不胜感激。

P.S。 - @SamRoberts猜测提到我的名字会起到“蝙蝠信号”的作用是正确的,吸引了我的注意力: - )

Accelerating MATLAB Performance book