Thread: Optimizing out virtual function calls at compile-time

  1. #1
    ¡Amo fútbol!
    Join Date
    Dec 2001
    Posts
    2,138

    Optimizing out virtual function calls at compile-time

    Will the compiler even attempt to do it? Here's the example I'm working with...

    Code:
    //MY_HEADER_H
    class Base{
    public:
         virtual void method1() = 0;
         virtual void method2() = 0;
         //...
    };
    
    class Derived1 : public Base{
    public:
         virtual void method1();
         virtual void method2();
    
    private:
         RandomData m_foo;
    };
    
    class Derived2 : public Base{
    public:
         virtual void method1();
         virtual void method2();
    
    private:
         OtherRandomData m_foo;
    };
    
    
    //MY_MAIN_CPP
    #include "MyHeader.h"
    
    int main(void){
         Base* foo = new Derived1;  //perhaps switch to Derived2
         foo->method1();
         foo->method2();
         delete foo;
         return 0;
    }
    As you can see here, I'm basically defining a common interface for easy testing. I'd like to be able to switch out between one implementation and another to test changes in performance. Other than that, the "virtual-ness" is not used; function calls can be determined at compile-time by visual inspection. I was wondering if the majority of compilers, or more specifically VS2010, would be intelligent to pick up on this and inline the proper calls or am I going to suffer the performance hit from this. Since this code needs to run quite fast, I'd like to avoid this but would also like to avoid the CRT pattern for reasons of readability (personal preference) and reworking of code.

    Thoughts?

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Yes, the compiler is in principle able to optimize that. But you're being completely unrealistic in thinking the time of a single virtual function call could possibly even register in such a test. The call takes what, 10 nanoseconds tops. Assuming (quite unrealistically) that the function you are measuring executes in twice that time (20 nanoseconds), that's 30 nanoseconds for the complete test, which is a time so small it cannot be accurately measured. In reality, that function is probably millions if not billions of times slower than a virtual call.

    In other words, I don't see any loop in your code, which means you're capable of getting a reasonably accurate time from a single call, which means the overhead of a single virtual call is for all practical purposes non-existent. If instead I had seen a loop, where you call your function thousands or millions of times, I would think maybe the overhead would be significant, but as it is you are worried about the weight of a bacteria on the deck of an ocean liner.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    In practice, you will likely find that your compiler does not substitute a direct call here. If there are any examples where it manages to make a direct call when calling through a pointer to the base class, those are probably limited to little test snippets of code that don't actually do anything useful.

    Where it does tend to substitute a direct call is where it's calling through either a concrete instance of the derived class or possibly through a pointer to the derived class.

    If your code needs to run "quite fast" then making lots of little calls repeatedly, virtual or otherwise, is probably not ideal.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    If your code needs to run "quite fast" then making lots of little calls repeatedly, virtual or otherwise, is probably not ideal.
    Having used virtual quite a bit in larger rendering systems that also incorporated the CLI I can confidently say that making lots of calls..virtual, CLR, or otherwise usually does not impact performance as much as one might think. In other words while virtual calls and function calls in general are considered to be 'slow' I really do not think they will be that much of an issue on any modern compiler.
    Last edited by VirtualAce; 01-25-2012 at 08:09 PM.

  5. #5
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    I'm a little confused about the subject of this thread.
    Isn't the whole point of having virtual functions the advantage of NOT having to set in stone which (derived's) function to call at a particular moment ?

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by manasij7479
    I'm a little confused about the subject of this thread.
    golfinguy4 wants compile time polymophism using the run time polymorphism of virtual functions instead of CRTP.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by VirtualAce View Post
    Having used virtual quite a bit in larger rendering systems that also incorporated the CLI I can confidently say that making lots of calls..virtual, CLR, or otherwise usually does not impact performance as much as one might think. In other words while virtual calls and function calls in general are considered to be 'slow' I really do not think they will be that much of an issue on any modern compiler.
    I largely agree.

    It's not necessarily ideal because it might indicate that code which is calling lots of tiny functions from a certain class could simply be a method within that class. But it depends, that might not be the situation. Darn hypothetical situations.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Optimizing recursive function calls
    By thetinman in forum C++ Programming
    Replies: 13
    Last Post: 04-10-2010, 06:19 PM
  2. Replies: 3
    Last Post: 10-28-2009, 09:25 AM
  3. Is virtual calls really slow or it is just bull........?
    By idleman in forum C++ Programming
    Replies: 41
    Last Post: 09-28-2009, 11:51 AM
  4. Problems with virtual function calls, please help
    By e66n06 in forum C++ Programming
    Replies: 12
    Last Post: 12-12-2007, 05:12 AM
  5. pure virtual calls in destructor
    By FillYourBrain in forum C++ Programming
    Replies: 2
    Last Post: 08-21-2003, 08:31 AM