4

我正在优化一个稍微大一点的函数(大约 80 行没有注释的代码)。

作为尝试让分析器为我完成工作的一部分,我取了 2 块代码并将它们放在单独的函数中(这应该只是暂时的,直到我可以将它们放回原处)。

有趣的是:我的测试用例花了 29.8 秒
将第一个块放入单独的函数后,我看到由于函数调用开销导致的小的性能损失。(30.2 秒)当我将第二段代码放入一个单独的函数中时,我获得了相当大的性能提升,降至 24.2 秒

第二段代码是插入一个相当大的链表,我打算用二叉树或其他东西替换它,但是这 20% 的改进仍然让我很困惑。

tl;dr:尝试优化代码并注意到将代码块放入单独的函数中使我的性能提高了 20%。这怎么可能?

编辑:确认也在发布版本中运行

4

2 回答 2

6

通过提取此代码块,您使函数更简单。也许这有助于编译器有效地编译函数。它可能减轻了注册压力,因为局部变量较少。

有时,这只是巧合。随机晃动代码很可能会改变性能(两种方式)。也许你只是碰巧取得了进步而不是恶化。

为什么“摇晃”会改变性能?它可能会改变地址对齐、分支预测、编译器对什么是热什么是冷的看法、CPU 指令缓存的使用。

从语义的角度来看,所有这些都是实现细节。然而,它们会影响性能。它们是非常不可预测的,因为它们在非常低的级别上工作并且非常复杂。

于 2012-04-29T16:56:30.063 回答
1

没有代码示例,很难给出一个体面的解释,但 usr 的答案在大多数编程语言的情况下是非常正确的。

但是,对于 Flash 编译器,我确实有所保留。根据经验,自内联(与您所做的相反)通常是优化闪存中函数的最佳方法之一,因为函数调用开销非常高。

话虽如此,我同意 usr 的观点,即具有较少的局部变量很可能是您会看到性能提升的原因。Flash 没有块级作用域,这意味着函数中声明的所有变量在调用函数时都会分配内存。如果您的第二个代码块声明了仅在该特定代码块中有用的变量,并且该代码仅有时运行(如果它在 if 语句中),则可以解释性能提升。

您可以看到性能提升的示例:

public function foo() : void
{
    var bar : MyObj;
    //do stuff with bar

    if(someValuesAreTrue)
    {
        var jad  : oObj;
        var jad2 : oObj;
        //etc
        //do something with jad
    }
}

//changed to 
public function foo() : void
{
    var bar : MyObj;
    //do stuff with bar

    if(someValuesAreTrue)
    {
        subFunc();
    }
}
private function subFunc() : void
{
    var jad  : oObj;
    var jad2 : oObj;
    //etc
    //do something with jad
}

如果这不是您所处的情况,我会非常好奇地看到一些代码,因为它可以更好地了解自内联的其他性能提升替代方案。

于 2012-04-30T10:28:12.107 回答