Live data from Hacker News

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

16bpp.net

31–40 of 385 posts

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

#31
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.

Intent is nice and all that, but I would like a "nonwithstanding" keyword instead that just lets me bypass that kind of "intent" without having to copy paste the entire implementation just to remove a pointless keyword or make a destructor public when I need it.

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

#32
post #22
post #16

Earlier quoted context omitted.

If you already have LTO, can't the compiler determine this information for devirtualization purposes on its own?

If your runtime environment has dynamic linking, then the LTO pass can't always be sure that a subclass won't be introduced later that overrides the method.

Aha! That makes sense. I wasn't thinking of that case. Thanks!

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

#33

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

Macros in C are a text replace and so it is hard to see from a debugger how th code got like that.

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

#34
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.

In general, I think things should be strict by default. Way easier to optimize and less error prone.

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

#35
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.

C++ doesn't have the fragile base problem, as members aren't virtual my default. The only concern with unintended inheritance is with polymorhpic deletion. "final" on class definition disables some tricks thag you can do with private inheritance.

Having said that "final" on member functions is great, and I like to see that instead of "override".

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

#36
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?

In general the compiler/linker cannot assume that derived classes won't arrive later through a shared object.

You can tell it "I won't do that" though with additional flags, like Clang's -fwhole-program-vtables, and even then it's not that simple. There was an effort in Clang to better support whole program devirtualization, but I haven't been following what kind of progress has been made: https://groups.google.com/g/llvm-dev/c/6LfIiAo9g68?pli=1

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

#37
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.

See this is why I find this odd.

Is there a theory as to how devirtualisation could hurt performance?

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

#38
I really wish he'd listed all the flags he used. To add on to the flags already listed by some other commenters, `-mcpu` and related flags are really crucial in these microbenchmarks: over such a small change and such a small set of tight loops, you could just be regression on coincidences in the microarchitecture scheduler vs higher level assumptions.

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

#39
post #26

I don't do much C++, but I have definitely found that engineers will just assert that something is "faster" without any evidence to back that up. Quick 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…

Even if one of these constructs is faster it doesn't matter 99% of the time.

Writing well structured readable code is typically far more important than making it twice as fast. And those times can rarely be predicted beforehand, so you should mostly not worry about it until you see real performance problems.

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

#40
post #26

I don't do much C++, but I have definitely found that engineers will just assert that something is "faster" without any evidence to back that up. Quick 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…

agreed, especially in cases like this. final is primarily a way to prohibit overriding methods and extending classes, and it indicates to the reader that they should not be doing this. use it when it makes conceptual sense.

that said, c++ is usually a language you use when you care about performance, at least to an extent. it's worth understanding features like nrvo and rewriting functions to allow the compiler to pick the optimization if it doesn't hurt readability too much.

Post reply on HN