首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么建议我不要使用只调用一次的内联函数?

为什么建议我不要使用只调用一次的内联函数?
EN

Software Engineering用户
提问于 2018-09-12 09:50:10
回答 3查看 2K关注 0票数 4

我对内联的理解如下:

标记为“内联”(假设编译器确实内联)的单独函数将被“合并”到调用的函数中。

即(伪码)

代码语言:javascript
复制
void main ()
{
  printf(b(2,3))  // will be printf(2*3*3);
}
inline function b(int x, int y)
{
  return x*y*y;
}

但是,我讨论了内联,为什么建议我不要在代码中调用一次内联函数(因为它们是初始化函数)?

例如:

代码语言:javascript
复制
void main(){
    initFunctionA();
    SomeType destinationA;
    SomeType destinationB;
    InitDescriptionType description;
    //initialize DescriptionType
    initFunctionB(&description, destinationA&);
    initFunctionC(&description, destinationB&);
}

inline void initFunctionA()
{
    //do stuff
}
inline void initFunctionB(InitDescriptionType* desc, SomeType** destination)
{
    // Take Description and put something into destination
}
inline void initFunction(InitDescriptionType* desc, SomeType** destination)
{
    // Take Description and put something into destination
}

这不意味着我的输出代码会稍微小一些(因为没有跳转到函数等)?

欧元dit:这个问题并没有回答我的问题。在我的例子中,初始化是一个单一的函数。我的想法是“嘿,为什么我不把我的信息化分解成多个更小的函数以提高可读性,并将它们内联?”

EN

回答 3

Software Engineering用户

回答已采纳

发布于 2018-09-12 10:39:53

在C和C++中,inline关键字具有使内联成为可能的效果,但也有许多其他效果--例如抑制一个定义规则(ODR)。这可以掩盖臭虫。

因此,inline关键字应该只用于必须在标头中定义的函数和其他对象。特别是,C++类定义中的任何函数定义都已隐式内联。

但是,如果您只想使编译器的内联优化成为可能,那么就给那些函数内部链接。这是可以通过static关键字,或因为C++11通过匿名名称空间。

注意,如果每个程序执行一次函数调用,那么优化该函数调用是不值得的。实际上,您不会注意到性能上的任何差异。与其优化初始化代码,不如找到真正的瓶颈:

  1. 确定您的实际性能要求。
  2. 分析您的代码以查找热点和昂贵的操作。
  3. 想办法避免那些昂贵的操作。在热点地区,微观优化有时会带来回报。
  4. 重复步骤2和3,直到您的性能要求得到满足为止。

另请参阅:

票数 8
EN

Software Engineering用户

发布于 2020-10-21 11:36:38

如果我们讨论的forceinline技术确实很有可能迫使编译器内联一个函数,而不是在C或C++中使用inline,我会重复相同的建议,即使在多次调用函数时也不要使用它,直到启动分析器并比较前后的结果。如果你提前得到快乐的内嵌函数,因为它们很小,或者只被调用一次,或者经常被调用,那么问题之一就是它会降低分析器给出的输出,因为它不再能准确地告诉你哪些非内联函数实际上构成了你的热点。

然而,我想跳进去的主要原因是,我有一个隐含的假设,即总是调用一次的函数内联可能总是会使事情运行得更快,这是因为代码稍微小了一点,并且消除了函数调用开销,尽管直觉是完全错误的。

多年来,我发现了很多这样的情况:通过重构将一个较小的函数从更大的函数中提升出来,有时甚至强行阻止编译器(和链接器)将它们与noinline嵌入,从而在效率上产生了可测量的提高(有时在操作上有2到3倍的速度提升)。一个简单的理由是,至少在没有PGO的情况下,优化器无法判断代码的哪些分支是常见的,因为它们是基于运行时输入的。只有非常有限的寄存器和这种性质的东西,所以如果我们只是将每一个被调用一次的函数内联到调用函数的主体中,它可能导致在公共情况分支中的效率较低的指令和更多的堆栈溢出。

我认为更多的开发人员应该注意到这一点,因为我在一个性能相当关键的领域工作,并且遇到了许多开发人员在分析之前都热切地试图强制执行内联功能,结果却发现了一些有意义的改进,实际上删除了这些提示,有时甚至用noinline替换它们。这是自然会发生的事情,但对于任何依靠他们的剖析者,不愿意尝试这样的东西,然后再测量。

票数 2
EN

Software Engineering用户

发布于 2020-10-21 12:28:39

您不需要内联来保存一些字节的代码。您所做的将创建一个巨大的函数,而不是几个较小的函数,这会导致更少的优化和可能更大、更慢的代码。

加上你有维修问题。这是不寻常的代码,所以下一个维护人员将浪费他们的时间,弄清楚为什么你要插入初始化代码。

票数 0
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/378327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档