当使用内联函数,何时不使用它呢? [英] When to use inline function and when not to use it?
问题描述
我知道,行内是一个提示或要求编译器和用于避免函数调用的开销。
所以,在什么基础上可以判断一个函数是否是内联或不是候选人?
在这种情况下,应该避免内联?
避免函数调用的成本只是故事的一半。
做的:
- 使用
在线
而不是的#define
- 很小功能是很好的候选
在线
:快code和较小的可执行文件(更多的机会留在$ C $ ç缓存) - 功能小和所谓经常
不要
- 大功能:导致更大的可执行文件,它显著降低性能无论是更快的执行从调用开销 的结果
- 内联函数是I / O密集型
- 的功能很少使用
- 构造函数和析构函数:即使当空,编译器生成code为他们
- 破开发库时,二进制兼容性:
- 内联现有的功能
- 改变一个内联函数或进行内联函数非内联:本库以前的版本叫老实施
您应该:
- 添加非内联虚析构函数即使身体是空
- 请所有构造非内联
- 写拷贝构造函数和赋值运算符的非内联的实现,除非该类不能通过值复制
记住在线
关键词是一个提示编译器:编译器可能会决定不内联函数,它可以决定内联未标记的功能在线
摆在首位。我一般避免标记(也许除了写作非常非常小的函数时)功能内联。
关于性能,明智的做法是(一如既往)分析的应用程序,那么最终在线
一组功能重新presenting的瓶颈。
参考文献:
- 内联或不内联
- [9]内联函数
- 策略/二进制兼容性问题的C ++
- GotW#33:内联
- 内嵌终极版
- C ++有效 - 项目33:使用内联的明智
编辑:Bjarne的Stroustrup的,C ++编程语言:
一个函数可以被定义为
在线
。例如:
块引用>内嵌INT FAC(INT N)
{
返回(正2)? 1:N * FAC(N-1);
}
的
在线
符是一个提示,它应该尝试生成code代表)的呼叫FAC(编译code>联,而不是一次放下code代表的功能,然后通过通常的函数调用机制调用。一个聪明的编译器可以生成恒
720
的通话FAC(6)
。那递归与否取决于输入等相互递归内联函数,内联函数的可能性,使得它不可能保证一个在线
函数的每一个电话实际上是内联。编译器的聪明程度无法立法,因此一个编译器可能会产生720
,另一个6 * FAC(5)
,还有一个一个未内嵌调用FAC(6)
。
若要在没有异常聪明的编译内联可能和连接设备的定义,并不仅仅是一个在线声明-的功能必须在范围(第9.2节)。一个
在线
especifier不影响功能的语义。特别是,内联函数仍具有一个唯一的地址,因此具有静态
变量(§7.1.2)内联函数的。
块引用>EDIT2:ISO-IEC 14882-1998,7.1.2功能符
一个函数声明(8.3.5,9.3,11.4)与
在线
指定符的内联函数。内联说明指示,在调用点函数体的内联替代是要pferred通常的函数调用机制$ P $的实施。实现不需要进行在调用点这个联替代;然而,即使省略此内联替代,内联函数由7.1.2定义的其他规则仍应受到尊重。
块引用>I know that inline is a hint or request to compiler and its used to avoid function call overheads.
So on what basis one can determine whether a function is a candidate for inlining or not ? In which case one should avoid inlining ?
解决方案Avoiding the cost of a function call is only half the story.
do:
- use
inline
instead of#define
- very small functions are good candidates for
inline
: faster code and smaller executables (more chances to stay in the code cache)- the function is small and called very often
don't:
- large functions: leads to larger executables, which significantly impairs performance regardless of the faster execution that results from the calling overhead
- inline functions that are I/O bound
- the function is seldom used
- constructors and destructors: even when empty, the compiler generates code for them
- breaking binary compatibility when developing libraries:
- inline an existing function
- change an inline function or make an inline function non-inline: prior version of the library call the old implementation
when developing a library, in order to make a class extensible in the future you should:
- add non-inline virtual destructor even if the body is empty
- make all constructors non-inline
- write non-inline implementations of the copy constructor and assignment operator unless the class cannot be copied by value
Remember that the
inline
keyword is a hint to the compiler: the compiler may decide not to inline a function and it can decide to inline functions that were not markedinline
in the first place. I generally avoid marking functioninline
(apart maybe when writing very very small functions).About performance, the wise approach is (as always) to profile the application, then eventually
inline
a set of functions representing a bottleneck.References:
- To Inline or Not To Inline
- [9] Inline functions
- Policies/Binary Compatibility Issues With C++
- GotW #33: Inline
- Inline Redux
- Effective C++ - Item 33: Use inlining judiciously
EDIT: Bjarne Stroustrup, The C++ Programming Language:
A function can be defined to be
inline
. For example:
inline int fac(int n) { return (n < 2) ? 1 : n * fac(n-1); }
The
inline
specifier is a hint to the compiler that it should attempt to generate code for a call offac()
inline rather than laying down the code for the function once and then calling through the usual function call mechanism. A clever compiler can generate the constant720
for a callfac(6)
. The possibility of mutually recursive inline functions, inline functions that recurse or not depending on input, etc., makes it impossible to guarantee that every call of aninline
function is actually inlined. The degree of cleverness of a compiler cannot be legislated, so one compiler might generate720
, another6 * fac(5)
, and yet another an un-inlined callfac(6)
.To make inlining possible in the absence of unusually clever compilation and linking facilities, the definition–and not just the declaration–of an inline function must be in scope (§9.2). An
inline
especifier does not affect the semantics of a function. In particular, an inline function still has a unique address and so hasstatic
variables (§7.1.2) of an inline function.EDIT2: ISO-IEC 14882-1998, 7.1.2 Function specifiers
A function declaration (8.3.5, 9.3, 11.4) with an
inline
specifier declares an inline function. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions defined by 7.1.2 shall still be respected.
这篇关于当使用内联函数,何时不使用它呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!