Same language. Same file. Two very different performance profiles

Same language. Same file. Two very different performance profiles, and you pick which one per method.
That's the real reason I prefer .NET for payment and fintech workloads. It isn't one feature. You can start with safe, readable code and drop to low-level code only where profiling tells you to, without leaving the language or the runtime.
What makes that possible:
Reified generics.
List<int>is a real list of ints, not boxed objects, and the JIT specializes value-type generics.Dynamic PGO. On by default since .NET 8, the runtime profiles hot methods while they run, then recompiles them with real data, including devirtualizing interface calls that always hit one type. An interface-heavy design can run closer to a direct call than the source suggests.
Span and ArrayPool. Where profiling points at a hot path, slice with
ReadOnlySpan<char>instead ofSplit, rent buffers instead of allocating them. Nounsafeneeded.Source generators. System.Text.Json,
GeneratedRegexandLoggerMessagemove reflection and regex construction to compile time, which is also what makes Native AOT workable.Built-in telemetry.
ActivityandMetership in the base library and line up with OpenTelemetry.
The honest trade-offs: GC still needs deliberate tuning on latency-critical paths, Native AOT restricts reflection and runtime code generation, and Rust still wins on compile-time data race checks.
I don't prefer .NET because it's the fastest at everything. I prefer it because I rarely have to leave it.
When did you last drop to low-level code inside a high-level stack, and what did the profiler show that made you do it?



