Live data from Hacker News

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

16bpp.net

291–300 of 385 posts

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

#291
post #285

Earlier quoted context omitted.

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

No, because that would make it internal to each object file, while what you want is for all object files to see the same memory location.

> No, because that would make it internal to each object file, while what you want is for all object files to see the same memory location.

I can see exactly one use for an effect like that: static variables within the function.

Are there any other uses?

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

#292
post #290

Earlier quoted context omitted.

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…

No, I meant that we've written a compiler, based on Roslyn, whose runtime for compiling the code has improved by 20 % when switching to .NET 6. 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.

Interesting! (I was way off the mark, not reading carefully, ha)

Is it a public project?

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

#293
post #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".

Now try a regular function, you will be blown away. No need to type "final"...

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

#294
>Personally, I'm not turning it on. And would in fact, avoid using it. It doesn't seem consistent.

I feel like we'd have to repeat these tests quite a few times to get to a decent conclusion. Hell small variations in performance could be caused by all sorts of things outside the actual program.

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

#295

Earlier quoted context omitted.

In my opinion, the only things that really matter are algorithmic complexity and readability. And even algorithmic complexity is usually only an issue a certain scales. Whether or not an 'if' is faster than a 'switch' is the micro of micro optimizations -- you better have a good reason to care. The question I would have for you is was your bunch of ifs more readable than a switch would be.

But a switch and an if-else *is* a matter of algorithmic complexity. (Well, at least could be for a naive compiler). A switch could be converted to a constant time jump, but the if-else would be trying each case linearly.

It's linear with respect to the number of cases, not the size of inputs. It's still O(1) in the sense of algorithmic complexity.

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

#296

The main case where I use final and where I would expect benefits (not covered well by the article) is when you are using an external library with pure virtual interfaces that you implement. For example, the AWS C++ SDK uses virtual functions for everything. When you subclass their classes, marking your classes as final allows the compiler to devirtualize your own calls to your own functions (GCC does this reliably).…

> For example, the AWS C++ SDK uses virtual functions for everything. When you subclass their classes, marking your classes as final allows the compiler to devirtualize your own calls to your own functions (GCC does this reliably).

I want to ask, and I sincerely mean no snark, what is the point?

When working with AWS through an SDK your code will spend most of the time waiting on network calls.

What is the point of devirtualizing your function calls to save an indirection when you will be spending several orders of magnitude more time just waiting for the RPC to resolve?

It just doesn't seem like something even worth thinking about at all.

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

#297
post #285

Earlier quoted context omitted.

No, because that would make it internal to each object file, while what you want is for all object files to see the same memory location.

> No, because that would make it internal to each object file, while what you want is for all object files to see the same memory location. I can see exactly one use for an effect like that: static variables within the function. Are there any other uses?

Global variables and the magic of a build system based on C semantics.

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

#298

>Personally, I'm not turning it on. And would in fact, avoid using it. It doesn't seem consistent. I feel like we'd have to repeat these tests quite a few times to get to a decent conclusion. Hell small variations in performance could be caused by all sorts of things outside the actual program.

AFAIU, these tests were ran 30 times each and apparently some took minutes to run, so it's unlikely that you'll get any different conclusions.

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

#299
post #7

Earlier quoted context omitted.

In my experience the compiler is pretty good at figuring out what is constant so adding const is more documentation for humans, especially in C++, where const is more of a hint than a hard boundary. Devirtualization, as can happen when you add a final, or the optimizations enabled by adding a restrict to a pointer, are on the other hand often essential for performance in hot code.

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 __attribute__((const)), but I don't see them often in real code (unfortunately).

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

#300

I'm surprised by this article. the author genuinely believes that a language construct to benefit performance was added to the language without anyone ever running any metrics to verify. "just trust me bro", is the quote. It's is an insane level of ignorance about how these things are decided by the standards committee.

And yet, results from current compilers show that results are mixed, in summary not making programs faster.
Post reply on HN