Live data from Hacker News

Performance Improvements in .NET 10

devblogs.microsoft.com

91–98 of 98 posts

Re: Performance Improvements in .NET 10

#91

C# is definitely fast. There are some benchmark games that I relied on in the past as a quick check and saw it as underwelming vs rust/c++. For example: https://benchmarksgame-team.pages.debian.net/benchmarksgame/... We see that the fastest C# version is 6 times slower than the rust/c++ implementation. But that's super deceiving because those versions use arena allocators. Doing the same (wrote this morning, actually…

> There are some benchmark games that I relied on in the past as a quick check …

Try looking at the "transliterated line-by-line literal" programs:

https://benchmarksgame-team.pages.debian.net/benchmarksgame/...

> But that's super deceiving because …

… that's labelled [ Contentious. Different approaches. ]

Try removing line 11 from

https://benchmarksgame-team.pages.debian.net/benchmarksgame/...

Re: Performance Improvements in .NET 10

#92
post #29

Earlier quoted context omitted.

That's impressive, considering a major release is sniped every year. I've never thought it would be that much of an improvement outside of synthetic benchmarks.

Managed devs have been begging for such fixes since the start, so many important perf gains were just left on the table at the same time we were being given the message that C++ and Javascript was the future. My exposure to it at MS was during the Win vs Dev Div conflict (the Steve Sinofsky / Steve Balmer era) and the message that managed software was slow was a core part of that battle.

.NET really failed most its efforts to stay relevant for Desktop applications. Microsoft never really followed through on good UI frameworks.

But ASP.NET core is a great platform for any kind of backend application.

Re: Performance Improvements in .NET 10

#93
We run a (pretty) big multi-tenant SaaS app on dotnet and I was literally able to downgrade our production servers from 4-core-16GB vms to 2-core-8GB on AWS when going from .NET 6 to .NET 8 (we only use LTS releases b/c compliance, don't ask). Super excited to try .NET 10. Also, almost zero breaking changes when bumping versions, which is very refreshing compared to the front-end world.

That said, while C# (and the dotnet runtime) are awesome, MS is doing it a disservice lately (poor tooling, Cursor/VSCode controversy etc. etc.) C# could've been so much bigger...

Re: Performance Improvements in .NET 10

#94
post #89

Earlier quoted context omitted.

I enjoy reading your comments here. Thanks for sharing your knowledge, I'll watch the talk. > Yes, and arenas may give such usage patterns a similar CPU/RAM knob to tracing collectors, but this level of control isn't free. In the end you have to ask yourself if what you're gaining is worth the added effort. For me using them has been very easy/convenient. My earlier attempts with Zig used alloc/defer free everywhere…

Sure, using arenas is very often straightforward, but it also very often isn't. For example, say you have a server. It's very natural to have an arena for the duration of some request. But then things could get complicated. Say that in the course of handling the transaction, you need to make multiple outgoing calls to services. They have to be concurrent to keep latency reasonable. Now arenas start posing some challe…

  When you have a really good JIT, as Java does, this tradeoff is gone
Is there a way to visualize the machine code generated by the JVM when optimizing the same kind of code as the examples shown in the talk you mention? I tried putting the following into godbolt.org, but i'm not sure I'm doing it right:

  public class DontForgetToFlush {
      public static void example(java.io.BufferedWriter w) throws java.io.IOException {
          w.write("a");
          w.write("b");
          w.write("c");
          w.write("d");
          w.write("e");
          w.write("f");
          w.write("g");
          w.flush();
      }
      public static void main(String... args) throws java.io.IOException {
          var os = new java.io.OutputStreamWriter(System.out);
          var writer = new java.io.BufferedWriter(os, 100);
          example(writer);
      }
  }

Re: Performance Improvements in .NET 10

#95
post #94
post #89

Earlier quoted context omitted.

Sure, using arenas is very often straightforward, but it also very often isn't. For example, say you have a server. It's very natural to have an arena for the duration of some request. But then things could get complicated. Say that in the course of handling the transaction, you need to make multiple outgoing calls to services. They have to be concurrent to keep latency reasonable. Now arenas start posing some challe…

When you have a really good JIT, as Java does, this tradeoff is gone Is there a way to visualize the machine code generated by the JVM when optimizing the same kind of code as the examples shown in the talk you mention? I tried putting the following into godbolt.org, but i'm not sure I'm doing it right: public class DontForgetToFlush { public static void example(java.io.BufferedWriter w) throws java.io.IOException {…

You can ask the JVM to dump the actual instructions (https://javanexus.com/blog/printing-assembly-code-hotspot-ji...).

Just note that there may be differences between the very old APIs (as in your example), and the newer NIO (https://docs.oracle.com/en/java/javase/24/docs/api/java.base...), and you need to pay attention to text output that undergoes characeter set encoding (as in your example) vs binary output.

Re: Performance Improvements in .NET 10

#96

This sort of post really makes me appreciate what's gone into the JVM. A lot of these optimizations are things that the JVM has long implemented. That's not a knock on C# either. Besides the JVM the only other place you'll see these sorts of optimizations are the likes of V8. It makes me happy to see MS investing in C# like this. I love the notion of having competing VMed languages.

I was wondering how the JVM and V8 stack up. Do you have a source for that claim? Genuinely curious.

Coming from the game dev world, I’ve grown more and more convinced that managed languages are the right move for most code. My reasoning is simple: most game developers don’t have the time or patience to deeply understand allocation strategy, span usage, and memory access patterns, even though those are some of the most performance-critical and time-consuming parts of programming to get right.

Managed languages hide a lot of that complexity. Instead of explaining to someone, “you were supposed to use this specialized allocator for your array and make sure your functions were array-view compatible”—something that’s notoriously tedious to guarantee in game engines given how few developers even think about array views—you just let developers write code and most of those problems go away.

I’m not saying everything should be managed. Core engine code should still live in the predictable, statically compiled world. But history shows it can work: projects like Jak and Daxter were written primarily in a custom LISPy scripting language, and even Ryujinx (RIP), the excellent Nintendo Switch emulator, is written entirely in C#.

Another strong technical reason is that managed JIT languages can profile at runtime and keep optimizing call sites based on actual usage patterns. Normally, developers would have to do this by hand or rely on PGO, which works but is painful to set up.

Industry standards make this harder to adopt since platforms like Sony still block JIT, but I think this is the direction we should be moving.

Re: Performance Improvements in .NET 10

#97
post #96

This sort of post really makes me appreciate what's gone into the JVM. A lot of these optimizations are things that the JVM has long implemented. That's not a knock on C# either. Besides the JVM the only other place you'll see these sorts of optimizations are the likes of V8. It makes me happy to see MS investing in C# like this. I love the notion of having competing VMed languages.

I was wondering how the JVM and V8 stack up. Do you have a source for that claim? Genuinely curious. Coming from the game dev world, I’ve grown more and more convinced that managed languages are the right move for most code. My reasoning is simple: most game developers don’t have the time or patience to deeply understand allocation strategy, span usage, and memory access patterns, even though those are some of the mo…

> Do you have a source for that claim? Genuinely curious.

Hmm, no real source for the claim, just a general interest in the two VMs. JVM for work and V8 partially for work. AFAIK, those are two of the VMs that are getting the highest amount of research in due to how they are positioned.

If you want more general information on V8, I suggest reading about the turbofan design docs [1].

The JVM first started doing a lot of these optimizations with Hotspot. Google poached the engineers that did Hotspot and put them to work on V8. That's why the two VMs tend to share similar optimizations.

> I’ve grown more and more convinced that managed languages are the right move for most code.

I tend to agree, to an extent.

The JVM is very fast, but it's also memory hungry and doesn't give up the memory it claims easily. That's due to the nature of the GC algorithms it employs and some historical constraints which bloat object size. One thing you get out of non-gced languages is much lower memory usage and much better live memory density (when done correctly).

[1] https://docs.google.com/presentation/d/1sOEF4MlF7LeO7uq-uThJ...

Re: Performance Improvements in .NET 10

#98
post #94
post #89

Earlier quoted context omitted.

Sure, using arenas is very often straightforward, but it also very often isn't. For example, say you have a server. It's very natural to have an arena for the duration of some request. But then things could get complicated. Say that in the course of handling the transaction, you need to make multiple outgoing calls to services. They have to be concurrent to keep latency reasonable. Now arenas start posing some challe…

When you have a really good JIT, as Java does, this tradeoff is gone Is there a way to visualize the machine code generated by the JVM when optimizing the same kind of code as the examples shown in the talk you mention? I tried putting the following into godbolt.org, but i'm not sure I'm doing it right: public class DontForgetToFlush { public static void example(java.io.BufferedWriter w) throws java.io.IOException {…

You can use jit watch: https://github.com/AdoptOpenJDK/jitwatch
Post reply on HN