0

I have a set of arithmetic-only functions, whose calls are not determined at the compilation but at run time. I intended to create a array of pointers to all of them, and to handle the call of them through the array indices (e.g. if (a>3) call the 3rd one).

Those functions will be called heavily and repeatedly in a loop, so they must be inlined for performance.

My question is, will such a call through inline member function pointers end up being inlined?

Thanks!

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;
}
Zhangyi Hu
  • 39
  • 1
  • 2
  • 3

4 Answers4

3

First of all, there's never a guarantee that a particular call will be inlined (short of using compiler-specific extensions) so the "surely" in your code is not a sure bet.

The function-pointer call in your example could be inlined (since the compiler can tell what function is being called using static analysis) but that example is contrived and I doubt your code is that simple.

With all that said, the more important question is why are you worrying about performance right now? Do you have actual hotspots identified using a profiler that you are trying to improve, or do you just have a "feeling" that this will be an issue?

Focus on writing clean, understandable and maintanable code, and then after it's written and debugged, you can focus on performance-tweaking it with micro-optimizations.

Nik Bougalis
  • 10,495
  • 1
  • 21
  • 37
  • I hate to say this, but I'm starting to get tired of everyone who blindly yells premature optimization. (regardless of whether or not it actually is the case here) – Mysticial Feb 05 '13 at 17:48
  • Generally speaking, I do too. And I try to avoid doing it. But in this case, this question really does beg for it. – Nik Bougalis Feb 05 '13 at 17:49
  • I usually agree with blind premature optimization calls on stuff like "Is < faster than <= ?" But in this case, it's actually a function call - which is significantly more expensive. – Mysticial Feb 05 '13 at 17:53
  • @Nik Bougalis Thank you! I haven't tested it yet. It is only my feeling. What's you suggestion on such a situation, when which function to call have to be decided at run time? – Zhangyi Hu Feb 05 '13 at 17:54
  • My suggestion is to tag functions that are smallish and very frequently called with `inline` and let the compiler decide what makes sense to inline. Then, you can profile the code and tweak/optimize things accordingly. Remember, that inlining actually has downsides too - it can dramatically increase code size, decrease cache hit ratios, etc. So it's not a panacea. @Mysticial is very well versed in optimization, so he may want to also chime in. – Nik Bougalis Feb 05 '13 at 17:59
  • 1
    I actually don't rely on `inline`. I only use it as a hint if I think it *might* matter. In cases where I absolutely need it to be inlined (because I know it matters), I abuse macros. I don't even bother with force-inline pragmas because I've seen enough cases with compilers being unable to properly optimize out all the parameter passing. (so the result is a bunch of unnecessary data-copies and conversions) – Mysticial Feb 05 '13 at 18:04
  • @Mysticial My name is Nik and I abuse macros for performance-tweaking too... ;) – Nik Bougalis Feb 05 '13 at 18:06
1

If the code decides at runtime which function to call, clearly, the function CAN NOT be inlined - there is no choice but to call it through a pointer. It is really a case of "can the compiler figure out what is happening or not". In a case where you call a function through a pointer based on some conditions, then the compiler will need to understand how the conditions affect which pointer is used. If the compiler can't decide this upon the point of compiling the code, it MUST use a function pointer.

So in your example code, the compiler can (if it chooses to do so) inline both foo and figure f.

But in case of, say,

In a constructor, for example:

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

In some other code, where the compiler doesn't have direct knowledge of what the x & y values were in construction:

*blah.*pf(); 

the call can not be inlined, because the compiler doesn't know if f or g is the function to call.

I hope this makes sense.

[I also wonder why you can't use virtual functions...]

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
0

In the general case, no, it won't. In your particular case where the compiler sees how the pointer to member is obtained and everything is visible to the compiler, it can.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
0

" Those functions will be called heavily and repeatedly in a loop, so they must be inlined for performance."

there is no such thing in now days.

for your inline ans : that call will be inlined or not depend on compiler.

Arpit
  • 12,767
  • 3
  • 27
  • 40
  • That's just not true - there are legitimate cases where inline will help, often tremendously. But they are few and far between. – Nik Bougalis Feb 05 '13 at 17:50
  • 1
    "there is no such thing in now days." - I beg to differ. It *does* matter in some cases. – Mysticial Feb 05 '13 at 17:50
  • its not the case for OP ,i'm sure on this. – Arpit Feb 05 '13 at 17:51
  • @Mysticial as you are more experienced you know better and i respect it and you must have an experience of it. but i really don't seen such code, only in theory i studied this. :) – Arpit Feb 05 '13 at 17:53
  • @NikBougalis if you have some sample code then please share the link if you can. – Arpit Feb 05 '13 at 17:55
  • 2
    @Arpit It's rare, but it can matter. If this happens to be in a critical loop and the function has only a few additions, then it will matter - a lot. That said, that's a lot of "ifs". But there are enough users who do actually profile first before asking. – Mysticial Feb 05 '13 at 17:56