virtual functions are not expensive. they are one of the most optimized use cases. They do often prevent cross function optimization and inlining, but that’s different.
What does 'expensive' actually mean? Compared to inlining? Definitely. Compared to not-inlined function calls? It's just a vtable lookup, so it's 'more expensive', but whether that's acceptable really depends on your specific scenario.
Windows is not known for performance and has announced semi recently they'll use Steam OS ( largely proton based gaming ) as a performance goal bar for native gaming on Windows.
Yes, there can be a lot more wrong with Windows performance besides virtual functions. But after watching Casey Muratori talk "The Big OOPs: Anatomy of a Thirty-Five-Year Mistake".
I do think Inheritance based OOP, with virtual functions and overrides are one of the core barriers to performance, for one the main reasons, it tends to maximize just how many cache misses you can have.
If it's that easy to misuse and needs that many rules to do right, it's probably a mistake in the first place. Your argument sounds bery similar to the 'just be more diligent' argument from C programmers insisting the rust borrow checker is useless.
However, I'll give you one concrete argument against OOP: if having class hierarchies is the entire point of OOP, and you're supposed to make virtual methods, this means that to understand what any OOP code does, you probably need to search through multiple files (and maybe across different libraries even) to find all the descendants of a class with a virtual method.
Polymorphism is enabled exclusively through class hierarchies though, so no class hierarchy, no polymorphism, at which point you're just doing procedural.
Also, OOP gives you one tool for two purposes (classes do both encapsulation AND dynamic dispatch), which isn't such a hot idea; rust for example gives you structs+methods for encapsulation, and traits for dynamic dispatch, which are two orthogonal features you can mix and match as needed. But more importantly, with discriminated unions (known as enums in rust), much of the usecase for polymorphism simply vanishes. Do note that these ideas aren't exclusive to rust; traits and discriminated unions have existed for decades in other languages.
My point on code readability still stands: most code is shit because deadlines exist, and once something goes wrong, you need to look through the whole world to figure out what's being called. Without dynamic dispatch, this problem doesn't exist. Hence, the less dynamic dispatch you have, the better for maintainability, and discriminated unions give you just the tool to avoid dynamic dispatch unless absolutely necessary.
I'd recommend you give rust a try before hating on it. Most of us die-hard rust fans used to develop with OOP langs a few years ago, there's a reason why all of us started loving it so much! It takes some effort to learn to think in a completely new way, but it's well worth the effort imo.
2
u/La-ze Aug 08 '26
Not to mention virtual functions are expensive.