CppCon 2018: Mateusz Pusz “Effective replacement of dynamic polymorphism with std::variant”
Vložit
- čas přidán 4. 06. 2024
- CppCon.org
-
Presentation Slides, PDFs, Source Code and other presenter materials are available at: github.com/CppCon/CppCon2018
-
This short talk presents how easy it is to replace some cases of dynamic polymorphism with std::variant. During the lecture, we will analyze and compare 2 implementations of the same simple Finite State Machine. It turns up that variant-based code is not only much faster but also it gives us the opportunity to define our interfaces and program flow much better. The talk will end up with the discussion of pros and cons of each approach and will try to give guidelines on when to use them.
-
Mateusz Pusz, Epam Systems
Chief Software Engineer
Software architect, chief developer, and security champion with more than 14 years of experience in designing, writing and maintaining C++ code for fun and living. C++ consultant, trainer, and evangelist focused on Modern C++. His main areas of interest and expertise are code performance, low latency, stability, and security.
Mateusz worked at Intel for 13 years and now he leads C++ Community at EPAM Systems. He is also a founder of Train IT that provides C++ trainings to corporations. Mateusz is an active voting member of the ISO C++ Committee (WG21) where, together with the best C++ experts in the world, he shapes the next official version of the C++ language. He is also a member of WG21 Study Group 14 (SG14) responsible for driving performance and low latency subjects in the Committee. In 2013 Mateusz won “Bench Games 2013” - worldwide competition in the C++ language knowledge.
-
Videos Filmed & Edited by Bash Films: www.BashFilms.com *-----*
Register Now For CppCon 2022: cppcon.org/registration/
*-----*
This is an interesting approach of FSM, regardless if the performance testing result was fair, this talk shows several important techniqued we may use:
1. dynamic_cast with polymophism
2. double(multiple) dispatch implemented with visitor pattern
3. double dispatch implemented with CTTP, say, static polymophism
4. new technique of std::variant wothout polymophism
Any way, it's a good talk, thanks!
love this talk
An very interesting technique. Thank you very much for the talk! I usually implement FSM so states and events do not contain data members and I can create them only once or make them static. That way dynamic memory allocation is not an issue. But I like the variant + visitor technique a lot, especially performance. Will try to use it when I have a chance. Awesome!
When you have a memory issue for your FSM, it is good to associate data to your states, so that you not only minimize the data of your FSM, but also you limit the scope of these data.
My FSM transitions don't return an optional state, but the transition itself does the next-state operation whenever required. This is less orthodox, but it is more efficient as there is not branch testing if the state must be changed and an superfluous copy.
At 9:23, why can't you use "this" as a pointer of the base event type in the 'dispatch' function so you don't have to overload in the state class?
It would have been nice to compare code size as well.
What about iteration using range for loop. Is that possible using something like this? I like this idea as I have been considering something similar by creating a class called Polymorph and anything of that type can be derived from and used like virtuals but the idea of for(auto& T: vector) I am not sure will carry over using something like this. The syntax of this looks terrible and it needs wrapped up if it is going to be widely used for public consumption.
You can use range-based for loop with variant
technique.
It looks like this:
using Variants = std::variant;
std::vector variants{T{}, U{}};
for (auto variant : variants) {
std::visit(DispatchFunctor{}, variant) ;
}
I'm currently writing a program that will use a similar technique using variant. I hope it brings those benefits
Measure first ;-)
Ofcourse you are writing a program...how else would you use a variant?
Redundancy!
QA guy is so irritating..
Throwing exceptions is not fine.
hmmm, union is problem. That means memory is reserved for the LARGEST type. So you cannot use it when you have limited memory and you require it all.
But if you're constantly allocating a type for a transition, then you're bound to dynamically allocate the largest type. Do you think this is better?
@@dr0bi it all depends on your application. If just need an interface to member functions and use pointers, virtual table lookup seems more memory efficient.
@@jhbonarius I see, so you mean in general? I thought you were commenting on the finite state machine implementation.
Hum, if you have a memory issue for a specific type you could always use for that type a smart pointer type and continue to use a variant, isn't it?
memory is cheap , speed is costly to sacrifice in HFT world. you can always stick in extra RAM if cost of opportunity lost is in millions.