3 ms·
Let's break down what "runtime" aka "VM" in this case means: - Metadata representation: type system, reflection - JIT compiler - PAL: low-level platform-spec
by neonsunset 3y ago
Let's break down what "runtime" aka "VM" in this case means:
- Metadata representation: type system, reflection
- JIT compiler
- PAL: low-level platform-specific code and interaction with kernel APIs that are mostly consumed by the JIT and GC themselves
- Garbage Collector
- Special features: string interning, threadlocals, ThreadPool, assembly (un)loading and reflection emit, etc.
Only some of the above is written in C++, mostly JIT, GC, and parts of type system facilities.
This contrasted with CoreLib (like C stdlib) which includes code for everything else:
- Primitives (string, int, long, etc., they are partially or fully special-cased by compiler for layout purposes, good example to see how it works - ZeroSharp)
- What you usually see in standard library like APIs for working with strings, file and network IO, math, etc.
CoreLib is written in pure C#.
My issue is with "C++ making C# run fast" which is not the case - the compiler does, and the goal it achieves can be done in most other languages which would only impact the time to JIT the code which would only impact the startup time and not the performance of the compiled C# code.
To give a better example, some features have been historically written in C++ but later on were rewritten in C# for either NativeAOT, which does extra compilation work (also written in C#) or both NativeAOT and regular CLR (you could think of it as the vast majority of CLR being shared but JIT and AOT being two slightly non-overlapping spheres which implement certain runtime features differently, with NativeAOT using C# for what was in C++ previously).
Examples of these are threadlocals/threadstatics and string interning, where rewriting threadlocal storage in C# enabled further optimization in the compiler to fully elide any interop calls to C++ land and completely inline reading of these values, massively improving performance for this case, while rewriting string interning in C# too improved its performance and usability and allowed to remove the legacy cruft that existed to make it work on NativeAOT (still old C++ version for regular CLR but it's a rarely used feature anyway).
Another example is all string searching and manipulation code, all memcpy/memmove routines are too written in C# and always get optimal performance because C# has rich SIMD and intrinsics API which reach optimal HW utilization without ever having to touch C++ because it already gets compiled to comparable asm.
Or ThreadPool, it used to be written in C++ and then has received a rewrite in C# to enable further evolution and performance improvements (like blocked thread detection, or allowing for small methods to be inlined which is not an option with C++).
The overarching trend throughout all versions of .NET after going OSS has been moving more and more C++ code to C#.