何时应使用内联函数
When should I use inline functions?
可能的重复项:
我什么时候应该为函数/方法写关键字"inline"?
我有一个关于 c++ 中的内联函数的问题。我知道内联函数用于用内联函数体替换每个外观。但我不知道什么时候使用它。据说内联函数可以提高性能,但是我什么时候应该考虑使用内联函数呢?
内联函数最适合对性能至关重要且在任何地方重用但编写起来很平凡的小代码存根。
但是,您也可以使用它们来拆分代码,因此您最终可能会将其拆分为几个 100 行长的方法,而不是 1000 行长函数。您可以内联这些内容,使其具有与 1000 行长方法相同的效果。
现代编译器将自动内联一些较小的方法,但是您始终可以手动内联较大的方法。
有许多关于此的资源,例如:
- http://msdn.microsoft.com/en-us/library/1W2887zk(v=vs.80(.aspx
- http://www.cplusplus.com/forum/articles/20600/
- http://www.glenmccl.com/bett_007.htm
- http://www.exforsys.com/tutorials/c-plus-plus/inline-functions.html
通常现代编译器足够智能,可以将某些小函数内联到一个极限(以空间增量(。您可以提供提示。当然,您将inline
小的重复函数来节省呼叫开销。
另请注意,有时,即使您提供了 inline
关键字,编译器也可以决定不内联该函数,因此它的使用(至少出于优化目的(在某种程度上提供了信息。
大多数现代编译器都足够聪明,可以应用内联函数的优化,可能最好让编译器来决定。
内联只是一个建议,编译器可以自由拒绝或应用它。
在以下情况下,您可以考虑使函数内联:
- 函数很小
- 您可以使用内联函数代替 preprocssor 指令
#define
inline
关键字的目的是允许您在多个编译单元中定义相同的函数(通常通过在多个源文件包含的头文件中定义它(。在某些编译器上,如果您希望编译器能够考虑将其内联到多个编译单元中,则这一点至关重要。
因此,如果您在头文件中定义一个函数,则应始终将其声明为 inline
,否则如果该文件来自多个源文件,则会收到链接错误。(如果它是一个类成员函数,你可以在类中定义它;这隐式声明它inline
(。如果你在源文件中定义它,那么如果你认为它是内联的良好候选项(例如,如果它很小,或者只从一个地方调用(,你可以inline
声明它。
但是,编译器通常认为他们比您更了解哪些函数;有些人可能会将inline
声明作为提示,而其他人可能会完全忽略它。有些可能会提供非标准扩展来强制函数内联(或不内联(;仅当您确定(通过测量(它会改进编译器的决定时才使用这些,因为不明智的内联可能会损害性能。
当您认为重复调用函数比简单地将函数主体放在主代码中花费更多时间时(换句话说,当函数主体较小且函数被重复调用时(,您应该使用内联函数。但是,编译器通常会优化代码,并且可能会忽略已定义为内联的函数。SO 上还有许多其他线程更详细地处理此问题。
之前所说的一切看起来都是正确的,我只是想警告你一个常见的错误,因为你谈到了性能。
一些程序员错误地认为"内联"=更快,因为节省了函数调用的开销。是的,开销被节省下来,但是如果你的内联函数编译成比函数调用更大的代码(函数调用发生得非常快(,整个代码就会变得更大。然后,它会增加您的代码不适合处理器缓存的可能性。缓存就是今天的一切...所以你的"内联"代码实际上会运行得更慢......
我会说使用"内联"仅适用于直接在 .h 中编写的琐碎的 getter/setter 函数。
对于其他所有内容,我建议不要使用"内联",让编译器自己决定。
还有一个一般建议:除了一般概念之外,在一切运行之前,您不应该考虑优化,并且可以测量哪些操作需要处理时间。它通常不到代码的 20%,因此您不会浪费时间盲目优化其他所有内容。通过测量,您可以立即查看优化(例如,在此处和那里添加一些内联(是否真的有效。
- 何时应通过引用传递矢量参数而不是按值传递矢量参数?
- 何时应在构造函数参数中使用 const C++?
- 函数何时应该内联?
- 函数可以应用于 std::optional,并返回一个可选值吗?
- 如何知道函数何时抛出以及何时使用noexcept
- 为什么或何时应在调用之前将可调用函数参数强制转换为右值?
- C++函数何时删除返回值?
- 点云库 (PCL) - 声明点云时何时应使用 ::P tr 的经验法则?
- 何时应使用 C++ 固定宽度整数类型,它们如何影响性能?
- C 虚拟函数何时派生类是最终的
- 记录器何时应刷新
- 何时应使用 [[maybe_unused]]
- 何时应在现代C++中使用(非标头)源文件
- 何时应使用模板化参数与构造参数
- 关键部分或静音是否真的是成员变量,或者何时应成为成员变量
- 何时应存储指向函数的引用或指针?
- 何时应删除默认的移动构造函数时令人困惑的事情
- 何时应通过常量引用传递运算符重载函数的参数
- 何时应在非成员函数之前编写关键字 'static'?
- 何时应使用内联函数