【问题标题】:Does a function that only calls another function slow things down?一个只调用另一个函数的函数会减慢速度吗?
【发布时间】:2012-02-06 23:40:39
【问题描述】:

我看到了一些类似这样的代码

int *func2(int *var) {
    //Do some actual work
    return var;
}

int *func1(int *var) {
    return func2(var);
}

int main() {
    int var;
    var = func1(&var);
    return 0;
}

这对我来说似乎是一种难以置信的浪费,但我认为中间函数以前可能有两个可以调用的函数,或者将来有一些扩展计划。我只是想知道像 gcc 这样的编译器是否可以检测到这种事情并消除实际程序中的无用函数,或者这种事情是否真的在运行时浪费了 CPU 周期?

【问题讨论】:

  • 您是专门询问 gcc 还是理论上的问题 - 编译器可以做到吗?
  • 两者都是,我在 Mac 和几台 Linux 机器上使用 gcc。但总的来说我很好奇,因为我真的很新,并且想知道是否只是为了保持低缩进级别而制作大量函数是个好主意。

标签: c compiler-construction compiler-optimization


【解决方案1】:

不要进行过早的优化。专注于编写可读的代码。即使没有优化,额外的函数调用对性能的影响也可能很小。编译器可以选择内联它。

如果您以后遇到性能问题,您可以测试和分析以找到瓶颈。

【讨论】:

    【解决方案2】:

    在大多数情况下,如果您将编译器优化调得足够高,那么这些微不足道的函数将是 inlined。因此没有开销。

    所以您的问题的答案是:是的,编译器通常足够聪明,可以消除调用。
    所以除非你需要,否则不要担心。

    您也可以使用inline 关键字使其更明确:(尽管编译器仍然可以随意忽略它)

    inline int *func1(int *var) {
        return func2(var);
    }
    

    【讨论】:

      【解决方案3】:

      超级快速的答案:是的,也许。

      快速回答:是的,但通常不足以让您关心,有时根本不关心。

      完整答案:如果函数都在同一个翻译单元中并且编译器不糟糕,那么额外的函数调用层只会被优化出来,并且会有影响在性能上。否则,如果您正在进行外部函数调用,预计会有很小但非零的性能成本。大多数时候这并不重要,但在每个周期都很重要的超短函数上,它可能会使你的程序慢两倍,甚至更糟。一些最坏的例子:

      1. getc 这样的函数,它只是从缓冲区中提取下一个字节、推进位置并返回(在缓冲区非空的常见情况下)。
      2. 一种通过简单操作推进状态机并返回的函数,例如处理 UTF-8 字符的单个字节。
      3. 锁定/同步原语。这是一种特殊情况,因为实际的原子内存访问应该支配执行时间,使得开销看起来微不足道。但是,如果您的预期用例只是为单个微不足道的操作(例如lock(); a++; unlock();)持有锁,那么如果锁被高度争用,即使是少量的额外时间持有锁也可能对争用性能产生巨大影响。李>

      最后,你应该做的答案是:以最自然的方式编写代码,直到测试/测量显示存在性能问题。只有这样你才应该考虑为了性能而丑化你的代码。

      【讨论】:

        【解决方案4】:

        这取决于编译器和运行时环境。如果方法调用在堆栈上,则增加堆栈会产生轻微的额外开销。但在这种情况下,一切都是指针,所以这也可能是一个尾调用,并且可能会被内联。内联/尾调用将导致函数操作类似于跳转而不是递增堆栈;这意味着它在运行时类似于循环或 goto。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-02-14
          • 1970-01-01
          • 1970-01-01
          • 2011-03-23
          • 2021-01-13
          • 1970-01-01
          • 2013-05-21
          • 1970-01-01
          相关资源
          最近更新 更多