【发布时间】:2010-08-24 06:47:53
【问题描述】:
嗨, 内联函数的确切用法是什么,内联函数究竟做了什么。 程序员必须在什么基础上选择函数作为内联函数。 我用谷歌搜索了答案,但我仍然更喜欢 stackoverflow。
【问题讨论】:
标签: c++ function macros inline
嗨, 内联函数的确切用法是什么,内联函数究竟做了什么。 程序员必须在什么基础上选择函数作为内联函数。 我用谷歌搜索了答案,但我仍然更喜欢 stackoverflow。
【问题讨论】:
标签: c++ function macros inline
C++ FAQ Lite定义:
当编译器对函数调用进行内联扩展时,函数的代码会插入到调用者的代码流中(概念上类似于#define 宏所发生的情况)。
这可以提高性能,这取决于无数其他事情,因为优化器可以在程序上集成被调用的代码——将被调用的代码优化到调用者中。
有关示例和更多详细信息,请参见同一页面。
【讨论】:
函数内联是由编译器完成的性能优化
对于编译为机器码的典型函数,您将拥有函数 prolog 和 Fepilog。 prolog 和 epilog 设置堆栈帧,保存寄存器,为本地分配空间,并根据调用约定执行任何其他操作。完成所有这些需要 CPU 周期。对于非常小的函数(例如属性 getter 和 setter),相对于函数中完成的实际工作,这个成本可能很高。这就是内联拯救这一天的地方:)
内联函数是您定义的函数,编译器已决定将其直接包含在调用它的方法中,而不是生成call 指令。换句话说,目标内联函数的实际机器代码被“内联”到调用方法的主体中。例如,如果 Foo 调用 Bar 和 Bar 是内联的,并且您在调试器下运行程序,您将看到 Bar 的说明 in Foo 的正文. Bar 的 epilog 和 prolog 可以丢弃。
大多数时候,您应该让编译器确定何时为您内联函数。内联并不神奇或免费。它增加了代码大小和变量的生存范围,并迫使编译器用更少的位置处理更多数据。正因为如此,编译器有一套复杂的启发式方法来确定何时成本是值得的。大多数编译器确实允许内联提示。对于 Visual Studio,请参阅 inline, __inline, and __forceinline。然而,即使有这些提示,编译器也可以随意忽略你并做它想做的事。
相关的编译器概念是大纲和部分内联(参见here),它们试图将冷的、不经常命中的代码块移出大型方法的主体,以改善缓存行为,甚至为内联方法铺平道路概述方法。
【讨论】:
http://www.parashift.com/c++-faq-lite/inline-functions.html
即使您指定了inline 标志,编译器也可能会忽略它。如果您正在编写一个库,并且认真考虑了您想要做出的性能保证(并对其进行了分析),那么您可以考虑将inline 添加到您的函数或方法中。即使这样,也不能保证您会在编译后的代码中看到任何差异,因为编译器可能已经决定内联它们,或者忽略您的请求。
关于性能的警告:内联并不总能提高性能,因为它还会增加代码的大小。
分析您的应用程序,找到您的瓶颈,在算法级别考虑更改,只有当您需要在一个内部循环中挤出最后一点性能时,您才会费心尝试内联函数、展开循环或其他微优化。
【讨论】: