将代码放入独立的函数中如何提高性能?

4

我有一个稍微复杂的函数(大约80行代码不含注释),我正在优化它。

作为尝试让性能分析器替我完成工作的一部分,我将两个代码块分别放到了不同的函数中(这只是临时的,等我把���们放回去就好了)。

有趣的是: 我的测试用例需要29.8秒
在我把第一个代码块放到��个单独的函数中后,由于函数调用开销,我看到了小的性能损失。(30.2秒) 当我把第二个代码块放到一个单独的函数中时,我得到了相当大的性能提升,时间缩短至24.2秒

第二个代码块是插入到一个相当大的链表中的,我计划用二叉树或其他东西替换它,但即使如此,这20%的改进对我来说仍然相当困惑。

简而言之:尝试优化代码并注意到将代码块放入单独的函数中可以让性能提高20%。那怎么可能呢?

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

2个回答

6
通过提取这一段代码,使得函数更简单。也许这有助于编译器高效地编译该函数,减轻寄存器压力,因为本地变量较少。
有时候,这只是巧合。随意搬动代码很可能会改变性能(两种方式都有可能)。 也许你只是碰巧遇到了改进而不是恶化。
为什么"搬动"会改变性能?它可能会改变地址对齐、分支预测、编译器对何为热点和冷点的看法以及CPU指令缓存使用。 所有这些都是从语义角度来看的实现细节。 然而它们影响着性能。 它们相当不可预测,因为它们在非常低的层面上工作,并且非常复杂。

1
我喜欢那个答案,那就是我目前采用的方法。我需要找到有关ActionScript编译器优化类型的资源,否则我感觉我就像在黑暗中摸索。 - Robot Rocker
1
我加入了一些更多的想法。 - usr

1

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

然而,当涉及到Flash编译器时,我还是有所保留。从经验来看,自我内联(与您所做的相反)通常是优化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
}

如果您不处于这种情况下,我非常想看看一些代码,因为它可以提供其他性能提升替代方案的更好见解。

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