Virtual function call optimization

Discussion in 'C++' started by cppquester, Sep 25, 2011.

  1. cppquester

    cppquester Guest

    Suppose I have:

    class B
    {
    public:
    virtual void foo() {}
    }
    class D: public B
    {
    public:
    void foo() {}
    }
    int main(int argc, char *argv[])
    {
    D* d = new D();
    d->foo();
    return 0;
    }

    Will foo() be called using late binding or like a regular function
    call?

    Thanks in advance
    Marc
    cppquester, Sep 25, 2011
    #1
    1. Advertising

  2. On 9/25/2011 8:42 AM, cppquester wrote:
    > Suppose I have:
    >
    > class B
    > {
    > public:
    > virtual void foo() {}
    > }
    > class D: public B
    > {
    > public:
    > void foo() {}
    > }
    > int main(int argc, char *argv[])
    > {
    > D* d = new D();
    > d->foo();
    > return 0;
    > }
    >
    > Will foo() be called using late binding or like a regular function
    > call?


    I'd venture a guess that it would be called like a regular function, but
    only if your compiler is smart enough to recognize that. In any case
    you can check it yourself by looking at the assembly code instead of
    *asking us*. There is no requirement in the Standard that says one way
    or the other.

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Sep 25, 2011
    #2
    1. Advertising

  3. cppquester

    Miles Bader Guest

    cppquester <> writes:
    > class B { public: virtual void foo() {} };
    > class D: public B { public: void foo() {} }
    > int main () { D* d = new D(); d->foo(); }
    >
    > Will foo() be called using late binding or like a regular function
    > call?


    It depends. The compiler is allowed to do either.

    Since the compiler can see the exact type of d in the above code, many
    compilers are able to optimize the call to foo into a normal function
    call, and even inline it, but other compilers will still call through
    the vtable.

    A quick check of some compilers installed here:

    g++ 4.4 calls through vtable
    g++ 4.5 calls through vtable
    g++ 4.6 direct call (but doesn't inline)
    g++ trunk direct call (can inline)
    clang++ 2.9 direct call (can inline)
    clang++ trunk direct call (can inline)

    -Miles

    --
    Ich bin ein Virus. Mach' mit und kopiere mich in Deine .signature.
    Miles Bader, Sep 25, 2011
    #3
  4. cppquester

    cppquester Guest

    Thank you all. Especially Miles.
    Marc

    @Victor:
    Why do you answer if the question bothers you?
    Yes, I could have looked into the assembly code, but my project runs
    on a variety of platforms. I do not have them all available all the
    time and I wanted to know for more platforms than the ones I do have
    available right now.
    Therfore I think it was completely ok to ask here. I see you sometimes
    criticizing people for asking something you think they should find out
    themselves. Maybe you should be more careful with that. In the end I
    could probably find out the answer to any question myself. It is just
    a matter of effort. To save this effort I ask. This is IMHO one of the
    ideas of the usenet.
    cppquester, Sep 26, 2011
    #4
  5. On 9/25/2011 11:24 PM, cppquester wrote:
    > Thank you all. Especially Miles.
    > Marc
    >
    > @Victor:
    > Why do you answer if the question bothers you?


    Bothers? Why do you think that?

    > Yes, I could have looked into the assembly code, but my project runs
    > on a variety of platforms. I do not have them all available all the
    > time and I wanted to know for more platforms than the ones I do have
    > available right now.
    > Therfore I think it was completely ok to ask here.


    Did I say it wasn't?

    > I see you sometimes
    > criticizing people for asking something you think they should find out
    > themselves.


    So? It's my *right* to criticize anybody for anything. It's my
    *opinion* and I am *entitled* to having it and expressing it.

    > Maybe you should be more careful with that.


    No, I don't think so.

    > In the end I
    > could probably find out the answer to any question myself.


    Yet you didn't.

    > It is just
    > a matter of effort. To save this effort I ask. This is IMHO one of the
    > ideas of the usenet.


    No, that's not "one of the ideas of the usenet". The idea of usenet is
    to conjure help where you are *unable* to find the answer or don't even
    know the direction in which to look.

    When you ask somebody else about something you can *easily* (like in
    this case) find out by yourself, you essentially show that "saving your
    own effort" by making others do the work for you is OK. Well, it isn't.
    My *firm* belief is that converting USEnet into ABUSEnet, you stop
    exercising your *brain* and instead exercise your typing fingers.
    That's the real problem, and I simply *pointed it out to you*.

    I suspect that your tone and your decision to give me shit for how I
    replied, shows that in reality you *are aware* that your actions are
    questionable and the fact that I pointed it out simply hit the nerve
    that was already giving you discomfort. Well, learn your lesson and
    move on.

    Good luck!

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Sep 26, 2011
    #5
  6. cppquester

    cppquester Guest

    On 26 Sep., 18:51, Victor Bazarov <> wrote:
    > On 9/25/2011 11:24 PM, cppquester wrote:
    >
    > > Thank you all. Especially Miles.
    > > Marc

    >
    > > @Victor:
    > > Why do you answer if the question bothers you?

    >
    > Bothers? Why do you think that?


    We getting completely OT, but as you ask:
    Because you complaint that I ask.


    > > Yes, I could have looked into the assembly code, but my project runs
    > > on a variety of platforms. I do not have them all available all the
    > > time and I wanted to know for more platforms than the ones I do have
    > > available right now.
    > > Therfore I think it was completely ok to ask here.

    >
    > Did I say it wasn't?


    So why criticizing me for asking?


    > > I see you sometimes

    >
    > > criticizing people for asking something you think they should find out
    > > themselves.

    >
    > So? It's my *right* to criticize anybody for anything. It's my
    > *opinion* and I am *entitled* to having it and expressing it.
    >
    > > Maybe you should be more careful with that.

    >
    > No, I don't think so.


    Please read on...


    > > In the end I

    >
    > > could probably find out the answer to any question myself.

    >
    > Yet you didn't.
    >
    > > It is just

    >
    > > a matter of effort. To save this effort I ask. This is IMHO one of the
    > > ideas of the usenet.


    Maybe it was not clear what I meant with effort:
    If the effort is to organize a couple of platforms, install several
    compilers, etc.
    something in the order of many hours: Why not just ask instead?
    Somebody might have done it already and is willing to share his
    knowledge.


    > No, that's not "one of the ideas of the usenet". The idea of usenet is
    > to conjure help where you are *unable* to find the answer or don't even
    > know the direction in which to look.
    > When you ask somebody else about something you can *easily* (like in
    > this case) find out by yourself, you essentially show that "saving your
    > own effort" by making others do the work for you is OK. Well, it isn't.
    > My *firm* belief is that converting USEnet into ABUSEnet, you stop
    > exercising your *brain* and instead exercise your typing fingers.
    > That's the real problem, and I simply *pointed it out to you*.


    I pointed out above that it would not have been as easy as you imply.
    You put it as I want others to do my work. But I think here it would
    have been maybe three or more hours (*) of my time vs. five minutes
    for the answerer (if he already knew the answer - I would not expect
    anybody to do research just to answer me).
    Another time it might be vice versa: Overal a win win situation,
    thanks to usenet.

    (* in fact my project even runs on platforms I do not have access to
    at all, where some contributers did the porting)


    > I suspect that your tone and your decision to give me shit for how I
    > replied, shows that in reality you *are aware* that your actions are
    > questionable and the fact that I pointed it out simply hit the nerve
    > that was already giving you discomfort. Well, learn your lesson and
    > move on.


    (I could now cite somebody (-:
    "It's my *right* to criticize anybody for anything. It's my
    *opinion* and I am *entitled* to having it and expressing it.")

    But it was for sure not my intention "to give you shit". I am sorry if
    it came over that way.
    I just wanted to let you know that IMHO your critics are not always
    justified. And for sure not here.

    Let me add that I respect you due to your activity and the good
    quality of your replies in this NG.
    You helped a lot of people, including me. Thank you and please
    continue to do so.


    > Good luck!

    Same to you!

    Marc
    cppquester, Sep 26, 2011
    #6
  7. On 09/26/2011 09:38 AM, cppquester wrote:

    > Maybe it was not clear what I meant with effort:
    > If the effort is to organize a couple of platforms, install several
    > compilers, etc.
    > something in the order of many hours: Why not just ask instead?
    > Somebody might have done it already and is willing to share his
    > knowledge.


    But that's not the question you asked: you didn't specify any platforms,
    compilers or anything else. You asked a generic question about C++.

    If you had said "I've tested this on Windows using Visual Studio 2010
    and Ubuntu 11.04 using gcc 4.5.1, but I need to know if it will be
    optimized on platforms X, Y and Z" the answers to your question would
    have been very different.
    Kevin P. Fleming, Sep 26, 2011
    #7
  8. cppquester

    cppquester Guest

    On Sep 26, 8:59 pm, "Kevin P. Fleming" <> wrote:
    > On 09/26/2011 09:38 AM, cppquester wrote:
    >
    > > Maybe it was not clear what I meant with effort:
    > > If the effort is to organize a couple of platforms, install several
    > > compilers, etc.
    > > something in the order of many hours: Why not just ask instead?
    > > Somebody might have done it already and is willing to share his
    > > knowledge.

    >
    > But that's not the question you asked: you didn't specify any platforms,
    > compilers or anything else. You asked a generic question about C++.
    >
    > If you had said "I've tested this on Windows using Visual Studio 2010
    > and Ubuntu 11.04 using gcc 4.5.1, but I need to know if it will be
    > optimized on platforms X, Y and Z" the answers to your question would
    > have been very different.


    Yes, it would have been: "Ask in a platform specific group" :)
    Which would have been ok, but I was expecting that it is clearly
    defined (to use a regular function call).
    Or at least a de facto standard.

    But as at least on some platforms late binding is used I found a
    solution (for all platforms):

    class B
    {
    public:
    virtual void foo() {}
    };

    class D: public B
    {
    public:
    void foo() { fooD();}
    void fooD() {}
    };

    int main(int argc, char *argv[])
    {
    D* d = new D();
    d->fooD();
    return 0;
    }
    cppquester, Sep 26, 2011
    #8
  9. cppquester

    cppquester Guest

    On Sep 26, 6:51 pm, Paavo Helde <> wrote:
    > cppquester <> wrote in news:d47cdff0-a16e-4bcc-
    > :
    >
    >
    >
    >
    >
    >
    >
    >
    >
    > > But as at least on some platforms late binding is used I found a
    > > solution (for all platforms):

    >
    > > class B
    > > {
    > > public:
    > > virtual void foo() {}
    > > };

    >
    > > class D: public B
    > > {
    > > public:
    > > void foo() { fooD();}
    > > void fooD() {}
    > > };

    >
    > > int main(int argc, char *argv[])
    > > {
    > > D* d = new D();
    > > d->fooD();
    > > return 0;
    > > }

    >
    > Just out of curiosity (as this gets discussed pretty often), how much did
    > avoiding this virtual call make your application faster? (I mean your
    > real application with realistic usage pattern and data, not the empty
    > example function here). How many percents did the slow operation go
    > faster?
    >
    > thanks
    > Paavo


    The project is actually an interpreter. If I use an (interpreted)
    program which makes heavy use of the code path I just changed to avoid
    the late binding, it speed up about 10%, which I find quite
    remarkable. My system did use late binding before.
    I think interpreters are one of the few fields where "every cycle
    counts".

    Cheers,
    Marc
    cppquester, Sep 26, 2011
    #9
  10. On 9/26/11 12:51 PM, Paavo Helde wrote:
    > cppquester<> wrote in news:d47cdff0-a16e-4bcc-
    > :
    >
    >> But as at least on some platforms late binding is used I found a
    >> solution (for all platforms):
    >>
    >> class B
    >> {
    >> public:
    >> virtual void foo() {}
    >> };
    >>
    >> class D: public B
    >> {
    >> public:
    >> void foo() { fooD();}
    >> void fooD() {}
    >> };
    >>
    >> int main(int argc, char *argv[])
    >> {
    >> D* d = new D();
    >> d->fooD();
    >> return 0;
    >> }

    >
    > Just out of curiosity (as this gets discussed pretty often), how much did
    > avoiding this virtual call make your application faster? (I mean your
    > real application with realistic usage pattern and data, not the empty
    > example function here). How many percents did the slow operation go
    > faster?
    >
    > thanks
    > Paavo
    >
    >
    >


    One spot where late binding can cost alot is that it prevents inlineing
    of code. If foo was an assessor function, then this could be significant.

    The key is that you must let the compiler know the static type of the
    object (or make it so that it can deduce it), to eliminate the late-binding.

    Using a none-virtual function connection is one way. Another way that
    should work is making your call

    d->D::foo();

    Another method, if you are willing to upgrade to C++11, and the object
    definition allows it, is to declair foo() to be final, as in

    class B
    {
    virtual void foo() {}
    };

    class D: public B
    {
    public:
    void foo() final ( ... }
    }

    since D::foo is final, late binding is not needed if the pointer has
    static type D.
    Richard Damon, Sep 27, 2011
    #10
  11. cppquester

    Miles Bader Guest

    Richard Damon <> writes:

    > Another method, if you are willing to upgrade to C++11, and the object
    > definition allows it, is to declair foo() to be final, as in

    ....
    > class D: public B
    > {
    > public:
    > void foo() final ( ... }
    > }
    >
    > since D::foo is final, late binding is not needed if the pointer has
    > static type D.


    Or sometimes more conveniently, declaring the whole class D to be final:

    class D final : public B
    {
    public:
    void foo();
    };

    (which has the advantage that it will make all methods final, even those
    D doesn't override)

    -miles

    --
    Accord, n. Harmony.
    Miles Bader, Sep 27, 2011
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. IK
    Replies:
    2
    Views:
    606
    hemraj
    Jul 23, 2004
  2. Replies:
    7
    Views:
    334
    Mike Smith
    Jul 27, 2006
  3. archimed7592
    Replies:
    4
    Views:
    741
    =?UTF-8?B?UGF3ZcWC?=
    May 30, 2007
  4. Szabolcs  Nagy

    function call optimization question

    Szabolcs Nagy, Sep 12, 2007, in forum: C Programming
    Replies:
    6
    Views:
    321
    Malcolm McLean
    Sep 12, 2007
  5. Ravikiran

    Zero Optimization and Sign Optimization???

    Ravikiran, Nov 17, 2008, in forum: C Programming
    Replies:
    22
    Views:
    861
    Thad Smith
    Nov 24, 2008
Loading...

Share This Page