Virtual dispatch in a loop

Viewed 142

I am wondering if there is a way to optimize case like following:

struct A{
   virtual process(int x) const = 0;
   virtual ~A() = default;
};

void useA(A const &a){
   for(int i = 0; i < 1000; ++i)
      a.process(i);
}

In case like this, if we promise somehow we wont change a vtable, the virtual lookup can be done only once, outside of the loop.

Is there a way to do something like this or result will be very negligible? Or probably there should be some other problem I do not see yet?

2 Answers

The whole reason the vtable gets checked every iteration in loop has to do with a ugly loophole in the language where you can destroy the object the virtual method is called on and recreate another object at the same memory. You can play some ping-pong that way and swap between classes every call of the virtual function.

I hope we all agree that such a code is unacceptable and we should be able to safely assume this doesn't happen in reasonable codebases. If so, you can tell the compiler about this with passing -fstrict-vtable-pointers on the command line of clang. I haven't found if GCC/MSVC supports the same flag.

Regarding the validity of the code I mentioned first, I found some C++ experts talk about this and still be confused, see the twitter conversion

Good question!

Firstly, instead of calling the virtual method directly, you could use the polymorphism to return a function, in the form of a functor, std::function or even a lambda, e.g.

struct A{
   virtual std::function<...signature...> getProcessMethod() = 0;
   virtual ~A() = default;
};

See the following resources: Why use functors over functions?

https://www.go4expert.com/articles/cpp-closures-functors-lamdas-stdfunction-t34654/


Once you have your function, you can then apply functional techniques to whatever the range/iterator/vector you're looping round. So you could use a std::transform to perform a map-reduce on the entire set using the function. This can be optimised to use a thread pool etc. How to replicate map, filter and reduce behaviors in C++ using STL?


For further information I wholeheartedly recommend Ivan Cukic's book on Functional Programming with C++ https://www.amazon.co.uk/Functional-Programming-C-Ivan-Cukic/dp/1617293814

Related