我有一组仅运算的函数,它们的调用不是在编译时确定的,而是在运行时确定的。我打算创建一个指向所有这些指针的数组,并通过数组索引处理它们的调用(例如,如果(a> 3)调用第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;
}
答案 0 :(得分:3)
首先,永远不会保证特定的调用将被内联(缺少使用特定于编译器的扩展),因此代码中的“肯定”并不是一个肯定的赌注。
示例中的函数指针调用可以内联(因为编译器可以使用静态分析来判断正在调用哪个函数)但是这个例子是设计的,我怀疑你的代码就这么简单。
尽管如此,更重要的问题是为什么你现在担心性能?您是否使用您正在尝试改进的探查器确定了实际热点,或者您是否“感觉”这将是一个问题?
专注于编写干净,可理解且可维护的代码,然后然后 编写和调试后,您可以专注于性能 - 调整它微观优化。
答案 1 :(得分:1)
如果代码在运行时决定调用哪个函数,显然,函数不能内联 - 除了通过指针调用它之外别无选择。这实际上是“编译器能否弄清楚发生了什么”的情况。在基于某些条件通过指针调用函数的情况下,编译器将需要了解条件如何影响使用哪个指针。如果编译器在编译代码时无法做出决定,那么必须使用函数指针。
因此,在您的示例代码中,编译器可以(如果选择这样做)内联foo
和图f
。
但是,例如,
在构造函数中,例如:
if (x > y) pf = foo::f(); else pf = foo::g();
在其他一些代码中,编译器并不直接了解x& y值正在构建中:
*blah.*pf();
无法内联调用,因为编译器不知道f
或g
是否是要调用的函数。
我希望这是有道理的。
[我也想知道为什么你不能使用虚函数...]
答案 2 :(得分:0)
在一般情况下,不,它不会。在您的特定情况下,编译器会看到如何获取指向成员的指针,并且编译器可以看到所有内容,它可以。
答案 3 :(得分:0)
“这些函数将在循环中被大量重复调用,因此必须内联它们以提高性能。”
现在没有这样的事情。
为你的内联ans: 该调用将内联或不依赖于编译器。