class MyClass
{
public:
MyClass()
{
m_dbLoopStart = 0.0;
m_dbLoopStop = 100.0;
m_dbLoopStep = 0.001;
}
// Which of the following methods complete in a shorter time?
void Foo1() const // This one?
{
for (double x=m_dbLoopStart; x<=m_dbLoopStop; x+=m_dbLoopStep)
{
f(x);
}
}
void Foo2() const // Or, this one?
{
for (double x=m_dbLoopStart; x<=m_dbLoopStop; x+=m_dbLoopStep)
{
2.0 * x + 1.0;
}
}
private:
double m_dbLoopStart, m_dbLoopStop, m_dbLoopStep;
inline static double f(double x)
{
return 2.0 * x + 1.0;
}
};
在Foo1()
和Foo2()
中,哪一个完成得更快?
在这种情况下,使用"inline"是多余的,因为在类定义中定义的函数默认是内联的。
话虽如此,将函数定义为内联并不意味着该函数必须内联,不将其定义为内联也不意味着编译器不会将该函数内联。
正如其他人已经说过的,在这种情况下,它不会有什么不同,优化,甚至循环应该被优化到没有代码,x被分配m_dbLoopStop的值(无论x是什么)。
如果使用内联函数,编译器可能仍然选择不复制函数本身的函数体,从而导致函数调用。如果你显式地编写函数体,那么肯定不会调用任何函数。
所以严格来说,它更快。
内联函数可能更快,因为它们避免了函数调用的开销和返回开销。请记住,编译器可以选择不使用内联函数。
在大多数翻译中,必须传递函数形参,并为形参和任何函数本地存储分配空间。在返回端,必须删除函数局部变量,通常返回一个值。
对于简单函数,如getter和setter,函数调用和返回的开销大于函数中的代码。因此,内联将加快这些函数。
内联函数也删除调用函数的分支指令。这减少了处理器清除指令缓存/管道的机会。尽管现代处理器已经实现了算法来减少分支指令的负面影响。
在我的编程实践中,我内联小(3行或更小)方法。如果出于性能考虑要内联,我会在内联之前进行概要分析。
调用带参数的内联函数与简单地使用复制/粘贴代码或#define宏之间通常存在细微的语义差异。例如,考虑宏和函数:
<>之前external void some_extern_function(int x);#define foo1(x) (some_extern_function((x)), some_extern_function((x)))无效内联foo2(int x) {some_extern_function(x);some_extern_function (x);}之前现在假设有人调用它们:
<>之前some_volatile_int;foo1 (some_volatile_int);foo2 (some_volatile_int);之前在这种情况下,内联函数foo2
必须复制some_volatile_int
,然后将该副本传递给some_extern_function
的两个调用。相反,宏必须加载some_volatile_int
两次。根据调用约定,任何一种方法都可能比另一种方法更快。