Live data from Hacker News

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

16bpp.net

331–340 of 385 posts

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

#331

The only thing worse than no benchmark is a bad benchmark. I don't think this really shows what `final` does, not to code generation, not to performance, not to the actual semantics of the program. There is no magic bullet - if putting `final` on every single class would always make it faster, it wouldn't be a keyword, it'd be a compiler optimization. `final` does one specific thing: It tells a compiler that it can b…

Not disagreeing with your point, but it couldn't be a compiler optimization, could it? The compiler isn't able to infer that the class will not be inherited anywhere else, since another compilation unit unknown to the class could inherit.

I assume it could be or is part of link time optimization when compiling an application rather than a library?

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

#332

The only thing worse than no benchmark is a bad benchmark. I don't think this really shows what `final` does, not to code generation, not to performance, not to the actual semantics of the program. There is no magic bullet - if putting `final` on every single class would always make it faster, it wouldn't be a keyword, it'd be a compiler optimization. `final` does one specific thing: It tells a compiler that it can b…

Not disagreeing with your point, but it couldn't be a compiler optimization, could it? The compiler isn't able to infer that the class will not be inherited anywhere else, since another compilation unit unknown to the class could inherit.

Possibly not in the default c++ language mode, but check out -fwhole-program-vtables. It can be a useful option in cases where all relevant inheritance relationships are known at compile time.

https://reviews.llvm.org/D16821

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

#333

One thing that wasn't mentioned in the article that I wished it did was the size of the compiled binary with and without final. Only reason I would expect the final version to be slower is that we are emitting more code because of inlining and that is resulting in a larger portion of instruction cache misses. Also, now that I think of it, they should have run the code under perf and compared the stats.

Yeah, really unsatisfying that there was no attempt to explain why it might be slower since it just gives the compiler more information to decide on optimizations which in theory should only make thins faster.

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

#334

The only thing worse than no benchmark is a bad benchmark. I don't think this really shows what `final` does, not to code generation, not to performance, not to the actual semantics of the program. There is no magic bullet - if putting `final` on every single class would always make it faster, it wouldn't be a keyword, it'd be a compiler optimization. `final` does one specific thing: It tells a compiler that it can b…

> `final` does one specific thing: It tells a compiler that it can be sure that the given object is not going to have anything derive from it.

...and the compiler can optimize using that information.

(It could also do the same without the keyword, with LTO.)

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

#335

Earlier quoted context omitted.

Yes, I'm well aware of the definition of a macro in C and C++. Macros are simpler than templates. You can expand them with a compiler flag.

when things get complex templete error messages are easier to follow. nobody makes complex macros but if you tried. (template error messeges are legendary for a reason. nested macros are worse)

> nobody makes complex macros

http://boost.org/libs/preprocessor

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

#336
post #5

I would say the most performance impact would give `constexpr` followed by `const`. I wouldn't bet any money on `final` which in C++ is a guard of inheritance, and C++ function invocation address is resolved the `vtable` hence final wouldn't change anything. Maybe the author was mistaken with `final` keyword in Java

> followed by `const`

Const can only ever possibly have a performance impact when used directly on variables. const pointers / references are purely for the benefit of the programmer - the compiler can assume nothing because the variable could be modified elsewhere or through another pointer/reference and const_cast is legal anyway unless the original variable was const.

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

#337
post #299

Earlier quoted context omitted.

Since "const" makes things read-only, being const correct makes sure that you don't do funny things with the data you shouldn't mutate, which in turn eliminates tons of data bugs out of the gate. So, it's an opt-in security feature first, and a compiler hint second.

How does const affects code generation in C/C++? Last time I checked, const was purely informational. Compilers can't eliminate reads for const pointer data, because const_cast exists. Compilers can't eliminate double calls to const methods, because inside function definition such functions can still legally modify mutable variables (and have many side effects). What actually may help is __attribute__((pure)) and __a…

Const affects code generation when used on variables. If you have a `const int i` then the compiler can assume that i never changes.

But you're right that this does not hold true for const pointers or references.

> What actually may help is __attribute__((pure)) and __attribute__((const)), but I don't see them often in real code (unfortunately).

It's disppointing that these haven't been standardized. I'd prefer different semantics though, e.g. something that allows things like memoization or other forms of caching that are technically side effects but where you still are ok with allowing the compiler to remove / reorder / eliminate calls.

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

#339
post #270
post #252

Earlier quoted context omitted.

The compiler simply knows that the actual dynamic type is Animal because it is not a pointer. You need Animal* to trigger all the fun virtual dispatch stuff.

I intuit vector is what was meant...

Yes. I reflexively avoid asterisks on this site because they can hose your formatting.

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

#340

Earlier quoted context omitted.

Not disagreeing with your point, but it couldn't be a compiler optimization, could it? The compiler isn't able to infer that the class will not be inherited anywhere else, since another compilation unit unknown to the class could inherit.

Possibly not in the default c++ language mode, but check out -fwhole-program-vtables. It can be a useful option in cases where all relevant inheritance relationships are known at compile time. https://reviews.llvm.org/D16821

Which is good, but may not apply. I have an application where I can't do that because we support plugins and so a couple classes will get overridden outside of the compilation (this was in hindsight a bad decision, but too late to change now). Meanwhile most classes will never be overriden and so I use final to saw that. We are also a multi-repo project (which despite the hype I think is better for us than mono-repo), another reason why -f-whole-program-vtables would be difficult to use - but we could make it work with effort if it wasn't for the plugins.
Post reply on HN