3 ms·
The main case where I use final and where I would expect benefits (not covered well by the article) is when you are using an external library with pure virtual
by mgraczyk 2y ago
The main case where I use final and where I would expect benefits (not covered well by the article) is when you are using an external library with pure virtual interfaces that you implement.
For example, the AWS C++ SDK uses virtual functions for everything. When you subclass their classes, marking your classes as final allows the compiler to devirtualize your own calls to your own functions (GCC does this reliably).
I'm curious to understand better how clang is producing worse code in these cases. The code used for the blog post is a bit too complicated for me to look at, but I would love to see some microbenchmarks. My guess is that there is some kind of icache or code side problem. where inlining more produces worse code.
- cogman10 2y agoCould easily just be a bad optimization pathway. `final` tells the compiler that nothing extends this class. That means the compiler can theoretically do things like inlining class methods and eliminate virtual method calls (perhaps duplicating the method)? However, it's quite possible that one of those optimizations makes the code bigger or misaligns things with the cache in unexpected ways. Sometimes, a method call can bet faster than inlining. Especially with hot loops. All this being said, I'd expect final to offer very little benefit over PGO. Its main value is the constraint it imposes and not the optimization it might enable.
- lpapez 2y ago> For example, the AWS C++ SDK uses virtual functions for everything. When you subclass their classes, marking your classes as final allows the compiler to devirtualize your own calls to your own functions (GCC does this reliably). I want to ask, and I sincerely mean no snark, what is the point? When working with AWS through an SDK your code will spend most of the time waiting on network calls. What is the point of devirtualizing your function calls to save an indirection when you will be spending several orders of magnitude more time just waiting for the RPC to resolve? It just doesn't seem like something even worth thinking about at all.
- mgraczyk 2y agoYeah that's was just the first public C++ library with this pattern that popped into my head. I just make all my classes final out of habit and don't think about it. I remove final if I want to subclass, but that almost never happens.