Embedded is diverse. I would not use .NET for small embedded, i.e. stuff running on Arduino or ESP32.
However, I have successfully used .NET runtime in production for embedded software running on top of more performant SoCs, like 4 ARMv7 cores, couple GB RAM, Linux kernel. The software still has large pieces written in C and C++ (e.g. NanoVG rendering library) but all higher-level stuff like networking, file handling, and GUI are in memory-safe C#.
* Span<T>: https://learn.microsoft.com/en-us/archive/msdn-magazine/2018...
* C# now has a limited borrow checker-like mechanism to safely handle local references: https://em-tg.github.io/csborrow/
* Here is a series of articles on the topic: https://www.stevejgordon.co.uk/writing-high-performance-csha...
* In general, avoid enterprise style C# (ie., lots of class and design patterns) and features like LINQ which allocate a lot of temporaries.
Then why would they add Span<T>, SIMD types and overhaul ref types in the first place?
If you link an example snippet of the type of code that gave you pause, I’m sure there is a better and more idiomatic way to write it.
C# is Java-but-with-lessons-learnt, and is significantly less verbose and "enterprisey" in typical usage.
Modern .NET 9 especially embraces compile-time code generation, a "minimal" style, and relatively high performance code compared to Java.
Even if the JVM is faster in benchmarks for hot loops, typical Java code has far more ceremony and overhead compared to typical C# code.
Can you give an example? I don't think this is true anymore for modern Java (Java 21+)
Java currently beats .NET by about 40%: https://www.techempower.com/benchmarks/#hw=ph&test=fortune&s...
I judge more idiomatic / typical code complexity by the length of stack traces in production web app crashes. Enterprise Java apps can produce monstrous traces that are tens of pages long.
ASP.NET Core 9 is a bit worse than ASP.NET Web Forms used to be because of the increased flexibility and async capability, but it's still nowhere near as bad as a typical Java app.
In terms of code length / abstraction nonsense overhead, have a look at the new Minimal APIs for how lightweight code can get in modern C# web apps: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/m...
What matters in practical scenarios is that ASP.NET Core is significantly faster than Spring Boot. If you have a team willing to use ActiveJ or Vert.x, you are just as likely have a team willing to customize their C# implementation to produce numbers just as good at web application tasks and much better at something lower level. There are also issues with TechEmpower that make it highly sensitive to specific HW/Kernel/Libraries combination in ways which alter the rankings significantly. .NET team hosts a farm to do their own TechEmpower runs and it just keeps regressing with each new version of Linux kernel (for all entries), despite CPU% going down and throughput improving in separate more isolated ASP.NET Core evaluations. Mind you, the architecture of ASP.NET Core + Kestrel, in my opinion, leaves some performance on the table, and I think Techempower is a decent demonstration of where you can expect the average framework performance to sit at once you start looking at specific popular options most teams use.
Smaller objects from dropping identity is nice but it really doesn't seem like it gives you more explicit memory layout, lifecycle, c interop etc that C# has with their structs. Maybe I'm missing something.
Also can recommend reading all the performance improvements blog posts by Stephen Toub as well as learning to understand disassembly at a basic level which .NET offers a few convenient tools to get access to.
Helped me a bunch to get Sharpl spinning, much appreciated.
That is if you don't want to get into unsafe code.
Apart from that (which simply concerns strings, as they're the great source of performance issues, all generic best practices, applicable to any language, should be followed.
There are plenty resources on the net, just search for it.
You should also pour one out for Longhorn, where internal politics tanked the idea, and eventually Windows team redid all those .NET based ideas into COM/C++, and were even proud of doing so (see Hilo sample documentation), hence why nowadays COM based libraries are the main way to expose modern Windows APIs (aka post Windows XP).
Had they collaborated instead, probably Windows would be closer to something like Android userspace nowadays.
Or for Ironclad, another one from Microsoft research, lesser known, also from the same research group, which even includes type safe Assembly,
https://www.microsoft.com/en-us/research/publication/safe-to...
Microsoft Research has plenty of work in such domains, they also had a LLVM like compiler framework, based on MSIL, called Phoenix, among other stuff, e.g. Dafny, FStar, Drawbridge, also come from OS projects.
Unfortunely classical Microsoft management has been more like it isn't Windows, it isn't shipping.
Nokia owns the shambling corpse that is Bell Labs. Looking beyond the English speaking world, I wouldn’t discount that the chaebols (LG, Samsung, Mitsubishi, etc) all have a few companies dedicated to research at the Bell Labs level.
The big take-away I got from this (admittedly quite old now) experiment is that getting advertised performance out of unmanaged languages for typical real-world (i.e., non-benchmark) tasks often requires a lot more care than people really account for. Nowadays memory dominates performance more so than CPU, and the combination of a JIT compiler and a good generational, compacting garbage collector - like C# and Java developers typically enjoy - often does a better job of turning idiomatic, non-hand-optimized code into something that minimizes walks of shame to the RAM chips.
I've been having a lot of fun with Java lately, the maturity of the language/implementation and libraries allows me to focus on the actual problem I'm solving in ways no other language can currently match.
https://github.com/codr7/tyred-java https://github.com/codr7/eli-java