Now for libraries, this is a different story. There I can imagine final keyword could have an impact.
The Performance Impact of C++'s `final` Keyword
281–290 of 385 posts
Re: The Performance Impact of C++'s `final` Keyword
#282> And probably, that reason is performance. That's the first problem I see with the article. C++ isn't a fast language, as it is. There are far too many issues with e.g. aliasing rules, lack of proper vectorization (for the runtime arch), etc. If you wish to have a relatively good performance for your code, try ISPC, which still allows you to get great performance with vectorization up to AVX-512, without turning to…
> That's the first problem I see with the article. C++ isn't a fast language, as it is. There are far too many issues with e.g. aliasing rules, lack of proper vectorization (for the runtime arch), etc. That's a bold statement due to the way it heavily contrasts with reality. C++ is ever present in high performance benchmarks as either the highest performing language or second only to C. It's weird seeing someone clai…
I'm ready to back this up. And no, I'm not confusing things - I work in HPC (realtime computer vision) and in reality the only thing we'd use C++ for is "glue", i.e. binding implementations of the actual algorithms implemented in other languages together.
Implementations could be e.g. in CUDA, ISPC, neural-inference via TensorRT, etc.
Re: The Performance Impact of C++'s `final` Keyword
#283I do not see how the final keyword would make a difference in performance at all in this case. The compiler should be able to build an inheritance tree and determine by itself which classes are to be treated as final. Now for libraries, this is a different story. There I can imagine final keyword could have an impact.
Re: The Performance Impact of C++'s `final` Keyword
#284I 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…
Yep. "Profiling or it didn't happen." The issue is that it's essentially impossible for even the most neckbeard of us to predict with a high degree of accuracy and precision the performance on modern systems impact of change A vs. change B due to the unpredictable nature of the many variables that are difficult to control including compiler optimization passes, architecture gotchas (caches, branch misses), and interp…
Re: The Performance Impact of C++'s `final` Keyword
#285Earlier quoted context omitted.
"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…
> 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. Traditionally you'd use `static` for that use case, wouldn't you? After all, `inline` can be ignored, `static` can't.
Re: The Performance Impact of C++'s `final` Keyword
#286I do not see how the final keyword would make a difference in performance at all in this case. The compiler should be able to build an inheritance tree and determine by itself which classes are to be treated as final. Now for libraries, this is a different story. There I can imagine final keyword could have an impact.
Re: The Performance Impact of C++'s `final` Keyword
#287You 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".
Changing an existing method way of calling (regular, virtual, static), changing visibility, overloading, introducing a name that clashes downstream, introducing a virtual destructor, making a data member non-copyable,...
Re: The Performance Impact of C++'s `final` Keyword
#288Earlier quoted context omitted.
See this is why I find this odd. Is there a theory as to how devirtualisation could hurt performance?
Practically - it never does. It is always cheaper to perform a direct, possibly inlined, call (devirtualization != inlining) than a virtual one. Guarded devirtualization is also cheaper than virtual calls, even when it has to do if (instance is SpecificType st) { st.Call() } else { instance.Call() } or even chain multiple checks at once (with either regular ifs or emitting a jump table) This technique is heavily used…
Re: The Performance Impact of C++'s `final` Keyword
#289Earlier quoted context omitted.
Practically - it never does. It is always cheaper to perform a direct, possibly inlined, call (devirtualization != inlining) than a virtual one. Guarded devirtualization is also cheaper than virtual calls, even when it has to do if (instance is SpecificType st) { st.Call() } else { instance.Call() } or even chain multiple checks at once (with either regular ifs or emitting a jump table) This technique is heavily used…
Caution! If you compare across languages like that, not all virtual calls are implemented equally. A C++ virtual call is just a load from a fixed offset in the vtbl followed by an indirect call. This is fairly cheap, on modern CPUs pretty much the same as a non-virtual non-inlined call. A Java/C# interface call involves a lot more stuff, because there's no single fixed vtbl offset that's valid for all classes impleme…
Also you are correct - virtual calls are not terribly expensive, but they encroach on ever limited* CPU resources like indirect jump and load predictors and, as noted in parent comments, block inlining, which is highly undesirable.
[0] https://github.com/dotnet/runtime/blob/5111fdc0dc464f01647d6...
[1] https://github.com/dotnet/runtime/blob/main/docs/design/core... (mind you, the text was initially written 18 years ago, wow)
* through great effort of our industry to take back whatever performance wins each generation brings with even more abstractions that fail to improve our productivity
Re: The Performance Impact of C++'s `final` Keyword
#290Earlier quoted context omitted.
Not sure about the 10×, either, and if true it would involve more than just the JIT changes. But changing ASP.NET to ASP.NET Core at the same time and the web server as well as other libraries may make it plausible. For certain applications moving from .NET Framework to .NET isn't so simple when they have dependencies and those have changed their API significantly. And in that case most of the newer stuff seems to be…
Roslyn didn't have much of changes in terms of optimizations - it compiles C# to IL so does very little of that, save for switches and certain new or otherwise features like collection literals. You are probably talking about RyuJIT, also called just JIT nowadays :D (the distinction becomes important for targets serviced by Mono, so to outline the difference Mono is usually specified, while CoreCLR and RyuJIT may not…
And indeed, on the C# -> IL side there's little that's being actually optimized. Besides collection literals there's also switch statements/expressions over strings, along with certain pattern matching constructs that get improved on that side.