0

我有一组仅算术函数,它们的调用不是在编译时确定的,而是在运行时确定的。我打算创建一个指向所有指针的数组,并通过数组索引处理对它们的调用(例如,如果 (a>3) 调用第三个)。

这些函数将在循环中被大量重复调用,因此必须内联它们以提高性能。

我的问题是,这种通过内联成员函数指针的调用最终会被内联吗?

谢谢!

class foo{
    private:
    int f(int x){return x;}
    int (foo::*pf)(int);
    public:
    foo(){
        pf=&foo::f;
        (*this.*pf)(3); //will this call be inlined?
        f(3);           //this call is surely inlined
    }
};
int main(){
    foo f;
    return 0;
}
4

4 回答 4

3

首先,永远不能保证特定调用会被内联(没有使用特定于编译器的扩展),因此代码中的“肯定”并不是一个确定的赌注。

您的示例中的函数指针调用可以内联(因为编译器可以使用静态分析来判断正在调用的函数)但是该示例是人为的,我怀疑您的代码是否那么简单。

说了这么多,更重要的问题是你为什么现在担心性能?您是否有使用探查器确定的实际热点并试图改进,或者您是否只是“感觉”这将是一个问题?

专注于编写干净、可理解和可维护的代码,然后 编写调试之后,您可以专注于通过微优化对其进行性能调整。

于 2013-02-05T17:46:50.183 回答
1

如果代码在运行时决定调用哪个函数,很明显,该函数不能被内联——别无选择,只能通过指针调用它。这实际上是“编译器能否弄清楚正在发生的事情”的情况。如果您根据某些条件通过指针调用函数,那么编译器将需要了解条件如何影响使用哪个指针。如果编译器在编译代码时无法决定这一点,它必须使用函数指针。

因此,在您的示例代码中,编译器可以(如果它选择这样做)内联foo和 figure f

但是,如果,比如说,

在构造函数中,例如:

if (x > y) pf = foo::f(); else pf = foo::g();

在其他一些代码中,编译器不直接知道 x 和 y 值在构造中是什么:

*blah.*pf(); 

调用不能被内联,因为编译器不知道是否f或者g是要调用的函数。

我希望这是有道理的。

【我也想知道为什么不能用虚函数……】

于 2013-02-05T18:33:41.517 回答
0

“这些函数将在循环中被大量重复调用,因此必须内联它们以提高性能。”

现在没有这样的事情。

对于您的内联 ans :该调用将被内联或不依赖于编译器。

于 2013-02-05T17:49:34.373 回答
0

在一般情况下,不,不会。在编译器看到如何获取指向成员的指针并且编译器可以看到所有内容的特定情况下,它可以。

于 2013-02-05T17:45:48.440 回答