.Net has evolved to become a platform for developing software that performs excellently.

Initially developed inhouse by Microsoft, it has now evolved into one of the most comprehensive open source ecosystems. Its latest incarnation .Net 9 is the most performant release to date.

C#

C# is the dominant programming language for the platform, with a syntax that is familiar to both C++ and Java developers. Unlike C++ where templates is a code generation feature integrated into the programming language, C# has generics which are compiled types that cannot be instantiated without specifying instantiable types for the generic parameters.

Traditionally .Net programs are compiled into intermediate code that are packaged as .Net assemblies that will be transformed by the JIT compiler, which is an integral part of the .Net runtime, into machine code at execution time.

.Net Native

.NET Native brings the performance benefits of C++ to managed code developers using the same, or similar, technologies as C++ to turn programs written for the .Net platform into native executables. Machine code generation for both are based on the UTC optimizing compiler, but .Net programs dynamically links against the MRT.dll runtime.

C# and .Net can now be used to implement number crunching solutions that challenges the performance of C++ and Rust, even without native compilation.

The table below shows the results, in seconds, for executing a set of common mathematical operations 1 000 000 000 times:

Test .Net 9 .Net Framework Standard C++ Optimized C++ Julia Python Rust
IsNaN 3,21131 3,6367279 1,1127655 1,0175695 1,41 188,573726 1.0229428
IsInf 3,3915906 3,6948053 1,0464091 1,0140321 0,999 191,919179 1.0457156
Abs 2,2755014 2,6035281 0,9712436 1,1597954 0,973 133,554733 0.9539125
FRExp 2,2708008 8,6199498 17,5162206 2,4895346 0,98 320,8951 2.4209312
ModF 2,261356 6,9360261 4,2012568 2,7641698 1,398 330,282251 1.9483226
Min 2,3673176 6,5788681 0,9763737 1,0012508 1,456 230,150583 0.9530636
Max 2,3819487 6,1213893 0,9706261 0,9790643 1,223 234,857767 0.9481684
Ceil 2,3127194 7,261466 1,1667381 0,9854143 1,148 288,997075 4.8385903
Floor 2,2406476 6,5273658 1,1646673 0,9711043 1,147 299,056741 4.2593385
Trunc 2,8116986 7,6517926 8,1095757 0,9861945 1,167 211,218895 8.2184693
Round 2,2979082 4,2840166 11,503602 1,0072632 1,213 291,214887 11.7508667
Lerp 1,2302819 2,1986549 2,3439255 1,1662787 1,222 197,52626 1.1492095
Sin 7,8218807 32,733977 7,4981783 7,3220644 8,385 210,231034 8.0410636
ASin 11,4004879 13,6180039 10,6491442 6,709916 6,386 217,004373 11.1567682
Cos 8,4738403 32,685339 7,0921574 7,0395165 8,541 209,697392 8.4506613
ACos 11,9971425 14,1201149 10,8390355 5,7188627 6,216 217,970242 11.4727166
Tan 11,9070397 41,6371849 10,6903641 10,6894836 12,331 223,032492 11.0177146
ATan 8,3657106 42,5579887 7,1827557 6,4776865 7,404 218,877134 7.3598513
ATan2 19,4174499 41,721993 25,4644532 15,4972265 14,985 274,691577 18.2896109
Sqrt 4,7177178 2,8413529 1,4642421 1,4638211 1,455 203,658153 1.4675657
Total 113,1543502 288,0305448 131,9637345 76,4602488 80,039 4693,409594 116.7654832

Clearly .Net has come a long way in terms of performance. Out of the box, only Julia, a platform that is seriously optimized for number crunching, performs better.

Executing common mathematical operations using .Net 9 is now 154 % faster than .Net Framework, 16 % faster than standard C++, 3 % faster than Rust ,and, hold your breath, 4 047 % faster than Python, while Julia performs 41 % better than .Net 9.

Getting C++ to perform as fast as Julia, took a bit of an effort, as this required carefully optimized versions of several of the standard math functions.

Links to the code used to perform the tests: