tldr: sprinkled a keyword around in the hopes that it "does something" to speed things up, tested it, got noisy results but no miraculous speedup. I started skimming this article after a while, because it seemed to be going into the weeds of performance comparison without ever backing up to look at what the change might be doing. Which meant that I couldn't tell if I was going to be looking at the usual random noise…
The Performance Impact of C++'s `final` Keyword
21–30 of 385 posts
Re: The Performance Impact of C++'s `final` Keyword
#22What final enables is devirtualization in certain cases. The main advantage of devirtualization is that it is necessary for inlining. Inlining has other requirements as well -- LTO pretty much covers it. The article doesn't have sufficient data to tell whether the testcase is built in such a way that any of these optimizations can happen or is beneficial.
If you already have LTO, can't the compiler determine this information for devirtualization purposes on its own?
Re: The Performance Impact of C++'s `final` Keyword
#23What should be evaluated is removing indirection and tightly packing your data. I'm sure you'll gain a better performance improvement. virtual calls and shared_ptr are littered in the codebase. In this way: you can avoid the need for the `final` keyword and do the optimization the keyword enables (de-virtualize calls). >Yes, it is very hacky and I am disgusted by this myself. I would never do this in an actual produc…
(But I'm worse than the author; if I'm just comparing performance, I'd probably put `final` everywhere applicable and then do separate compiles with `-Dfinal=` and `-Dfinal=final`... I'd be making the assumption that it's something I either always or never want eventually, though.)
Re: The Performance Impact of C++'s `final` Keyword
#24Re: The Performance Impact of C++'s `final` Keyword
#25You should use final to express design intent. In fact I’d rather it were the default in C++, and there was some sort of an opposite (‘derivable’?) keyword instead, but that ship has sailed long time ago. Any measurable negative perf impact should be filed as a bug and fixed.
Kotlin (which uses the equivalent of the Java "final" keyword by default) uses the "open" keyword for that purpose.
Re: The Performance Impact of C++'s `final` Keyword
#26Quick example, I got in an argument with someone a few years ago that claimed in C# that a `switch` was better than an `if(x==1) elseif(x==2)...` because switch was "faster" and rejected my PR. I mentioned that that doesn't appear to be true, we went back and forth until I did a compile-then-decompile of a minimal test with equality-based-ifs, and showed that the compiler actually converts equality-based-ifs to `switch` behind the scenes. The guy accepted my PR after that.
But there's tons of this stuff like this in CS, and I kind of blame professors for a lot of it [1]. A large part of becoming a decent engineer [2] for me was learning to stop trusting what professors taught me in college. Most of what they said was fine, but you can't assume that; what they tell you could be out of date, or simply never correct to begin with, and as far as I can tell you have to always test these things.
It doesn't help that a lot of these "it's faster" arguments are often reductive because they only are faster in extremely minimal tests. Sometimes a microbenchmark will show that something is faster, and there's value in that, but I think it's important that that can also be a small percentage of the total program; compilers are obscenely good at optimizing nowadays, it can be difficult to determine when something will be optimized, and your assertion that something is "faster" might not actually be true in a non-trivial program.
This is why I don't really like doing any kind of major optimizations before the program actually works. I try to keep the program in a reasonable Big-O and I try and minimize network calls cuz of latency, but I don't bother with any kind of micro-optimizations in the first draft. I don't mess with bitwise, I don't concern myself on which version of a particular data structure is a millisecond faster, I don't focus too much on whether I can get away with a smaller sized float, etc. Once I know that the program is correct, then I benchmark to see if any kind of micro-optimizations will actually matter, and often they really don't.
[1] That includes me up to about a year ago.
[2] At least I like to pretend I am.
Re: The Performance Impact of C++'s `final` Keyword
#27I'm surprised that it has any impact on performance at all, and I'd love to see the codegen differences between the applications. Mostly the `final` keyword serves as a compile-time assertion. The compiler (sometimes linker) is perfectly capable of seeing that a class has no derived classes, but what `final` assures is that if you attempt to derive from such a class, you will raise a compile-time error. This is simil…
"inline" is confusing in C++, as it is not really about inlining. Its purpose is to allow multiple definitions of the same function. It is useful when you have a function defined in a header file, because if included in several source files, it will be present in multiple object files, and without "inline" the linker will complain of multiple definitions. It is also an optimization hint, but AFAIK, modern compiler ig…
Re: The Performance Impact of C++'s `final` Keyword
#28What final enables is devirtualization in certain cases. The main advantage of devirtualization is that it is necessary for inlining. Inlining has other requirements as well -- LTO pretty much covers it. The article doesn't have sufficient data to tell whether the testcase is built in such a way that any of these optimizations can happen or is beneficial.
If you already have LTO, can't the compiler determine this information for devirtualization purposes on its own?
Re: The Performance Impact of C++'s `final` Keyword
#29I'm surprised that it has any impact on performance at all, and I'd love to see the codegen differences between the applications. Mostly the `final` keyword serves as a compile-time assertion. The compiler (sometimes linker) is perfectly capable of seeing that a class has no derived classes, but what `final` assures is that if you attempt to derive from such a class, you will raise a compile-time error. This is simil…
Re: The Performance Impact of C++'s `final` Keyword
#30What final enables is devirtualization in certain cases. The main advantage of devirtualization is that it is necessary for inlining. Inlining has other requirements as well -- LTO pretty much covers it. The article doesn't have sufficient data to tell whether the testcase is built in such a way that any of these optimizations can happen or is beneficial.
If you already have LTO, can't the compiler determine this information for devirtualization purposes on its own?