我知道内联是对编译器的提示或请求,用于避免函数调用开销。
那么,在什么基础上可以确定一个函数是否是内联的候选人? 在哪种情况下应该避免内联?
我知道内联是对编译器的提示或请求,用于避免函数调用开销。
那么,在什么基础上可以确定一个函数是否是内联的候选人? 在哪种情况下应该避免内联?
当前回答
此外,在维护大型项目时,内联方法有严重的副作用。当内联代码被更改时,所有使用它的文件将由编译器自动重建(如果它是一个好的编译器)。这可能会浪费大量的开发时间。
当内联方法被传输到源文件而不再内联时,整个项目必须重新构建(至少这是我的经验)。当方法转换为内联时也是如此。
其他回答
避免函数调用的开销只是故事的一半。
do:
使用inline代替#define 非常小的函数适合内联:更快的代码和更小的可执行文件(更多的机会留在代码缓存中) 这个函数很小,并且经常被调用
别:
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
在开发一个库的时候,为了让一个类将来可以扩展,你应该:
即使主体为空,也要添加非内联虚析构函数 使所有构造函数都是非内联的 除非类不能按值复制,否则编写复制构造函数和赋值操作符的非内联实现
记住,inline关键字是给编译器的一个提示:编译器可能决定不内联某个函数,也可能决定内联那些一开始就没有标记为内联的函数。我通常避免将函数标记为内联(可能在编写非常非常小的函数时分开)。
关于性能,明智的方法(一如既往)是分析应用程序,然后最终内联一组表示瓶颈的函数。
引用:
内联还是不内联 [9]内联函数 c++的策略/二进制兼容性问题 GotW #33:内联 内联回来的 有效的c++ -项目33:明智地使用内联
编辑:Bjarne Stroustrup, c++编程语言:
函数可以定义为内联的。例如:
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 of fac() 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 constant 720 for a call fac(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 an inline function is actually inlined. The degree of cleverness of a compiler cannot be legislated, so one compiler might generate 720, another 6 * fac(5), and yet another an un-inlined call fac(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 has static variables (§7.1.2) of an inline function.
EDIT2: ISO-IEC 14882-1998, 7.1.2功能说明
使用内联说明符的函数声明(8.3.5,9.3,11.4)声明了一个内联函数。内联说明符向实现指示,在调用点对函数体进行内联替换将优先于通常的函数调用机制。实现不需要在调用点执行这种内联替换;然而,即使省略了这个内联替换,7.1.2中定义的内联函数的其他规则仍应遵守。
只有当函数代码很小时,才应该使用内联函数限定符。如果函数比较大,则应该使用普通函数,因为节省内存空间可以换取相对较小的执行速度牺牲。
最好的方法是检查和比较生成的内联和非内联指令。但是,省略内联总是安全的。使用内联可能会导致您不想要的麻烦。
当你认为你的代码足够小,可以作为内联使用,记住内联函数复制你的代码,并在函数被调用时粘贴它,这样可能会增加你的执行时间,但也会增加内存消耗。 当你使用循环/静态变量/递归/切换/goto/虚函数时,你不能使用内联函数。 虚的意思是等到运行时,内联的意思是在编译期间,所以它们不能同时使用。
最好的方法是分析你的程序,把那些被多次调用并消耗CPU周期的小函数标记为内联函数。这里的关键字是“小”——一旦函数调用开销与函数中花费的时间相比可以忽略不计,那么内联它们就没有意义了。
我建议的另一种用法是,如果你有一些小函数在性能关键代码中经常被调用,以至于缓存不相关,你可能也应该内联这些函数。同样,这也是侧写师应该能够告诉你的。