使用内联函数与直接在代码中编写函数体一样快

Is using an inline function as fast as directly writing the function body in the code?

本文关键字:函数体 一样 代码 函数      更新时间:2023-10-16
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两次。根据调用约定,任何一种方法都可能比另一种方法更快。