Live data from Hacker News

The Performance Impact of C++'s `final` Keyword

16bpp.net

11–20 of 385 posts

Re: The Performance Impact of C++'s `final` Keyword

#11
1% is nothing to scoff of. But I suspect that the variability of compilation (specifically quirks of instruction selection, register allocation and function alignment) more than mask any gains.

The clang regression might be explainable by final allowing some additional inlining and clang making an hash of it.

Re: The Performance Impact of C++'s `final` Keyword

#12
That's interesting. Maybe final enabled more inlining, and clang is being too aggressive about it for the icache sizes in play here? I'd love to see a comparison of the generated code.

I'm disappointed the author's conclusion is "don't use final", not "something is wrong with clang".

Re: The Performance Impact of C++'s `final` Keyword

#13
post #6

You 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.

[deleted]

Re: The Performance Impact of C++'s `final` Keyword

#15
post #3

I'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…

> The compiler (sometimes linker) is perfectly capable of seeing that a class has no derived classes

How? The compiler doesn't see the full program.

The linker I'm less sure about. If the class isn't guaranteed to be fully private wouldn't an optimizing linker have to be conservative in case you inject a derived class?

Re: The Performance Impact of C++'s `final` Keyword

#16
post #2

What 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

#17

That's interesting. Maybe final enabled more inlining, and clang is being too aggressive about it for the icache sizes in play here? I'd love to see a comparison of the generated code. I'm disappointed the author's conclusion is "don't use final", not "something is wrong with clang".

Or "something is wrong with my benchmark setup", which is also a possibility :)

Without a comparison of generated code, it could be anything.

Re: The Performance Impact of C++'s `final` Keyword

#18
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 of performance testing or something real.

For `final`, I'd want to at least see if it changing the generated code by replacing indirect vtable calls with direct or inlined calls. It might be that the compiler is already figuring it out and the keyword isn't doing anything. It might be that the compiler is changing code, but the target address was already well-predicted and it's perturbing code layout enough that it gets slower (or faster). There could be something interesting here, but I can't tell without at least a little assembly output (or perhaps a relevant portion of some intermediate representation, not that I would know which one to look at).

If it's not changing anything, then perhaps there could be an interesting investigation into the variance of performance testing in this scenario. If it's changing something, then there could be an interesting investigation into when that makes things faster vs slower. As it is, I can't tell what I should be looking for.

Re: The Performance Impact of C++'s `final` Keyword

#19
post #16
post #2

What 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?

At the level that LLVM's LTO operates, no information about classes or objects is left, so LLVM itself can't really devirtualize C++ methods in most cases

Re: The Performance Impact of C++'s `final` Keyword

#20
post #3

I'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 ignore it.

Post reply on HN