Sealed in C# — More than a visual keyword

Let’s talk about the sealed keyword in C# and how the compiler is able to sometimes do a micro-optimization because of it. That means the keyword is not only a good habbit from a readability standpoint, but could increase performance as well.

Friedel Verpoort
Quick Code

--

Let me first explain very broadly how inheritance works on a compiler level. Basically every class that is inherited from parent class, inherits all properties and the important part is that it also inherits all methods. Methods are just memory location in assembly to where the code execution pointer should jump to. When we as programmers define virtual functions, the compiler generates a vtable in the backend. Without going to much into details when we call a virtual function it will jump to that vtable entry. After that we will jump to the location where that vtable entry points to. As a sidenote a vtable actually does take up a little bit of space, this is something programmers aren’t always aware of.

When using the sealed keyword and if the compiler will have the confidence to make a direct method call and by consequence optimize and skip the vtable lookup completly. This won’t give you any massive performance gains, but it did improve performance when I used sealed consistently in a game engine’s hot-path. Next to that it also is good practice to explicitly express that the class wasn’t intended to be overwritten and remove any assumptions. This is both for future programmers on the project as well as for compilers of course.

This extra bit of information you are giving to the compiler helps it understand your code just a little better. I will have a little bit of an extra deepdive on the compilers side, but for most readers just remember to use the sealed keyword where you feel like it is appropriate.

Photo by Alexander Sinn on Unsplash

Compiler Deepdive

You can see the exact implementation of this in the clang compiler(C++) here and it is worth noting that all compilers might have a slightly different implementation. However the general idea will be cross-compiler compatible. This technique has been used in Doom as well and fabian neatly explains how they got away with very little vtable lookups under unrolling the loop. Unity also has a nice article about this and uses an example to show the improvements.

Cover image by Karolina Grabowska from Pexels.

--

--

Friedel Verpoort
Quick Code

Fill his days as a freelance game developer. Also loves writing from time to time and generally enjoys life.