I remember reading online somewhere that in EXTREMELY low latency situations its better to use virtual functions as a substitute for IF statements.
Is this true? Are they basically saying dynamic polymorphism is better for speed situations?
Do any users have any other C++ low latency "quirks" they could share?
Objects of classes with virtual functions have only a small space-overhead compared to those that don't have virtual functions. Calling a virtual function is fast — almost as fast as calling a non-virtual function. You don't get any additional per-call overhead no matter how deep the inheritance gets.
The main advantage of virtual functions are that they directly support object oriented programming. When you declare a function as virtual you're saying that exactly what code is executed depends on the type of the object you call it against. you can't tell exactly what code path it's going to follow.
A virtual function is a member function that you expect to be redefined in derived classes. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class's version of the function.
There is no difference for the compiler, when you write the virtual in the derived class or omit it. But you need to look at the base class to get this information. Therfore I would recommend to add the virtual keyword also in the derived class, if you want to show to the human that this function is virtual.
I very much doubt that a single if/else statement would be slower than using a virtual function: the virtual function typically enforces a pipeline stall and limits the optimization opportunities. An if statement may stall the pipeline but if it is often executed the prediction may go the right way. However, if your alternative is between a cascade of a few if/else statements vs. just one virtual function call than that latter may be faster. Also, if the total code being executed via using virtual functions vs. branches is different functions ends up substantially smaller it may cause few cache misses on the instruction cache. That is, it depends on the situation. The best way is to measure. Note that measuring artificial code which is just attempting to investigate the difference between two approaches but doesn't really do any processing yields misleading results. However, when you need to produce very low latency code you typically can spend more time to come up with it, i.e. experimenting with multiple different approaches may be viable.
Although my colleagues tend to frown upon my template approaches for avoiding run-time branching, the code I end up with often is very slow to compile but very fast to run. Of course, this depends on the functions or branches being used to be known at compile time. In the areas I have used this e.g. for message processing it is often sufficient to have one dynamic decision e.g. one for each message (i.e. one virtual function call), followed by processing which doesn't involve any dynamic types (this are still conditionals, e.g. for the amount of values in a table).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With