0

I have the following class hierarchy (actually there are a whole lot more classes), I was wondering if its possible to reorganize the following to make use of static polymorphism?

struct return_val {};

struct base
{
   virtual ~base(){}
   virtual return_val work(){};
};

struct derivedtype1 : public base
{
   return_val work() { return localwork(next_type.work()); }
   return_val localwork(return_val& rv0){....}
   base* next_type0;
};

struct derivedtype2 : public base
{
   return_val work() { return localwork(next_type0.work(),next_type1.work()); }
   return_val localwork(return_val& rv0, return_val& rv1){....}
   base* next_type0;
   base* next_type1;
};

struct derivedtype3 : public base
{
   return_val work() { return localwork(next_type0.work(),next_type1.work(),next_type2.work()); }
   return_val localwork(return_val& rv0, return_val& rv1, return_val& rv2){.....}
   base* next_type0;
   base* next_type1;
   base* next_type2;
};

I ask as after having done a great deal of profiling, the overhead from virtual method calls is actually quite large and was hoping to optimize it away as much as possible.

Eric
  • 19,525
  • 19
  • 84
  • 147
Jared Krumsie
  • 397
  • 1
  • 8
  • 17
  • 3
    It's really quite simple: Do you know the final type at compile time? Then you can use some static genericity. If you don't, you do require runtime polymorphism and there's no way around. – Kerrek SB Mar 10 '12 at 22:32
  • @Kerrek: You're probably right, run-time is what I'm looking for, but i was hoping there was a secret c++ trick or something to get around the overhead of the vf call. – Jared Krumsie Mar 10 '12 at 22:35
  • 2
    That overhead doesn't really exist, it's so small as to being basically unnoticeable unless you have *really* tight performance requirements. – Xeo Mar 10 '12 at 22:55
  • 1
    @Xeo: Its noticeable for the current task I'm working on, the overhead is about 18% of total compute time. I've tried to refactor the code, so as to make the least number of vf calls, so at the moment vf overhead is the next thing to look at... – Jared Krumsie Mar 11 '12 at 01:53
  • I'm not sure how you are profiling your code to get that 18% number (your computation must be doing very little work relative to the number of vf calls you are making!) Anyhow, have you looked at answers in posts such as this: http://stackoverflow.com/questions/6599132/cost-of-a-virtual-function-in-a-tight-loop – kfmfe04 Mar 11 '12 at 07:24

1 Answers1

2

Because you mention 18% vf call overhead, I am assuming many virtual functions in each class. In that case, it might be possible to try this:

base * pObj;
switch(pObj->getTypeIdentifier())
{
  case 1:
    static_cast<derivedtype1*>(pObj)->func1;
    static_cast<derivedtype1*>(pObj)->func2;
    ...

  case 2:
    static_cast<derivedtype2*>(pObj)->func1;
    static_cast<derivedtype2*>(pObj)->func2;
    ...
}

This is basically what a virtual dispatch does for each func1, func2, etc. Difference here is you'll need to switch only once even when you access several functions - equivalent of single virtual dispatch.

vidit
  • 957
  • 1
  • 8
  • 23