仅调用另一个函数的函数会减慢速度吗?

问题描述 投票:0回答:4

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

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 周期?

c compiler-optimization
4个回答
12
投票

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

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


4
投票

在大多数情况下,如果你将编译器优化调得足够高,这些琐碎的函数将被内联。因此没有任何开销。

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

您还可以使用

inline
关键字使其更加明确:(尽管编译器仍然可以自由地忽略它)

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

1
投票

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

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

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

    getc
  1. 这样的函数只是从缓冲区中提取下一个字节,前进位置,然后返回(在缓冲区非空的常见情况下)。
    通过简单操作推进状态机并返回的函数,例如处理 UTF-8 字符的单个字节。
  2. 锁定/同步原语。这是一种特殊情况,因为实际的原子内存访问应该主导执行时间,使得开销看起来微不足道。但是,如果您的预期用例只是为单个简单操作持有锁(例如
  3. lock(); a++; unlock();
  4. ),那么如果锁竞争激烈,即使增加少量的锁定时间也可能会对争用性能产生巨大影响。
    
    
    
  5. 最后,你应该做什么的答案:以最自然的方式编写代码,直到测试/测量表明存在性能问题。只有这样你才应该考虑为了性能而丑化你的代码。


0
投票

© www.soinside.com 2019 - 2024. All rights reserved.