在C ++中使用内联函数的优点/缺点是什么?我看到它只会提高编译器输出的代码的性能,但是使用当今优化的编译器,快速的CPU,巨大的内存等(不像1980年那样,当时内存不足,所有内容都必须容纳100KB内存),他们今天真的有优势吗?
inline
是一个c ++关键字,而内联是一种编译器优化技术。有关正确答案,请参见此问题“ 何时应inline
为功能/方法编写关键字 ”。
在C ++中使用内联函数的优点/缺点是什么?我看到它只会提高编译器输出的代码的性能,但是使用当今优化的编译器,快速的CPU,巨大的内存等(不像1980年那样,当时内存不足,所有内容都必须容纳100KB内存),他们今天真的有优势吗?
inline
是一个c ++关键字,而内联是一种编译器优化技术。有关正确答案,请参见此问题“ 何时应inline
为功能/方法编写关键字 ”。
Answers:
内联函数更快,因为您不需要像往常一样将参数和返回地址压入/弹出堆栈。但是,它的确会使您的二进制文件稍大。
它有很大的不同吗?对于大多数人来说,在现代硬件上还不够明显。但这可以有所作为,对某些人来说就足够了。
内联标记并不能保证它是内联的。这只是对编译器的建议。有时,例如当您具有虚函数或涉及递归时,这是不可能的。有时,编译器只是选择不使用它。
我可以看到这样的情况产生了明显的变化:
inline int aplusb_pow2(int a, int b) {
return (a + b)*(a + b) ;
}
for(int a = 0; a < 900000; ++a)
for(int b = 0; b < 900000; ++b)
aplusb_pow2(a, b);
return 42 ;
语句。对我来说,这是极端的内联。它在现实生活中很少发生,它使编译时间更长,不会膨胀您的代码,并使您的代码更快。但是,就像圣杯一样,不要尝试将其应用到任何地方,因为大多数处理都无法通过这种方式解决...尽管如此,这仍然很酷... 3.2/6: There can be more than one definition of [..] inline function with external linkage [..] non-static function template
。在5.1.5 / 6 For a generic lambda, the closure type has a public inline function call operator member template
。并7.1.2/2: the use of inline keyword is to declare an inline function
建议在调用点内联函数体。因此,我得出结论,即使内联函数和函数模板可以表现相同,它们仍然是相互独立的,可以混合的正交概念(即内联函数模板)
在古老的C和C ++中,inline
就像register
:对编译器的关于可能的优化的建议(仅是建议)。
在现代C ++中,inline
告诉链接器,如果在不同的翻译单元中找到多个定义(不是声明),则它们都相同,并且链接器可以自由保留一个,而丢弃所有其他定义。
inline
如果在头文件中定义了一个函数(无论多么复杂或“线性”),则该函数是强制性的,以允许多个源包含该函数而不会导致链接程序出现“多个定义”错误。
默认情况下,在类内部定义的成员函数为“内联”,而模板函数也为“内联”(与全局函数相反)。
//fileA.h
inline void afunc()
{ std::cout << "this is afunc" << std::endl; }
//file1.cpp
#include "fileA.h"
void acall()
{ afunc(); }
//main.cpp
#include "fileA.h"
void acall();
int main()
{
afunc();
acall();
}
//output
this is afunc
this is afunc
请注意,将fileA.h包含在两个.cpp文件中,从而导致两个实例afunc()
。链接器将丢弃其中之一。如果未inline
指定,则链接器将抱怨。
内联函数是编译器使用的优化技术。可以简单地在函数原型之前添加inline关键字以使函数内联。内联函数指示编译器在代码中使用该函数的位置插入该函数的完整主体。
它不需要函数调用开销。
它还可以在函数调用时节省堆栈上变量push / pop的开销。
它还节省了从函数返回调用的开销。
它通过利用指令高速缓存来增加引用的局部性。
内联之后,如果指定,编译器还可以应用过程内优化。这是最重要的一个,通过这种方式,编译器现在可以专注于消除死代码,可以更加注重分支预测,归纳变量消除等。
要查看更多信息,请点击以下链接 http://tajendrasengar.blogspot.com/2010/03/what-is-inline-function-in-cc.html
在优化过程中,即使您未标记函数,许多编译器也会内联函数。如果您不了解编译器,通常只需要将函数标记为内联即可,因为它通常可以自行做出正确的决定。
一般来说,如今,任何现代编译器都担心内联任何东西,这几乎是在浪费时间。编译器实际上应该通过自己对代码的分析以及传递给编译器的优化标志的规范来为您优化所有这些注意事项。如果您关心速度,请告诉编译器优化速度。如果您关心空间,请告诉编译器优化空间。作为另一个暗示,一个体面的编译器甚至会在真正有意义的情况下自动内联。
另外,正如其他人所述,使用内联并不能保证任何内联。如果要保证它,则必须定义一个宏而不是一个内联函数。
何时内联和/或定义一个宏以强制包含?-仅当已知的关键代码段的速度得到了证明的和必要的事实证明的提高时,已知该代码的关键部分会影响应用程序的整体性能。
这并不关乎性能。C ++和C均用于硬件上的嵌入式编程。例如,如果要编写中断处理程序,则需要确保可以立即执行代码,而无需交换其他寄存器和/或内存页。那就是内联派上用场的时候。优秀的编译器在需要速度时会自行执行一些“内联”,但是会“强制内联”。
我们的计算机科学教授敦促我们不要在c ++程序中使用内联。当被问到为什么时,他友好地向我们解释了现代编译器应该检测何时自动使用内联。
所以是的,内联可以是在可能的情况下使用的一种优化技术,但是很显然,只要有可能内联函数,这已经为您完成。
来自此处另一次讨论的结论:
内联函数有什么缺点吗?
显然,使用内联函数没有错。
但是值得注意以下几点!
内联的过度使用实际上会使程序变慢。根据函数的大小,对其进行内联会导致代码大小增加或减少。内联一个非常小的访问器函数通常会减小代码大小,而内联一个非常大的函数则可以大大增加代码大小。在现代处理器上,由于更好地使用了指令高速缓存,因此较小的代码通常可以更快地运行。-Google指南
内联函数的速度优势往往会随着函数大小的增加而减少。在某些时候,与函数主体的执行相比,函数调用的开销变小,并且失去了好处-源
内联函数在某些情况下可能不起作用:
__inline
仅当您指定optimize选项时,该关键字才会使函数内联。如果指定了optimize,则是否接受优化__inline
取决于内联优化器选项的设置。默认情况下,只要运行优化器,内联选项就会生效。如果指定optimize,则如果要__inline
忽略关键字,还必须指定noinline选项。-资源
inline
关键字,所以上面提到的所有观点都是错误的。如果编译器使用关键字进行内联(它们仅用于确定标记多个定义以进行链接),则它们将为true。