Live data from Hacker News

Performance Improvements in .NET 7

devblogs.microsoft.com

71–80 of 164 posts

Re: Performance Improvements in .NET 7

#71
> A huge amount of effort in .NET 7 went into making code gen for Arm64 as good or better than its x64 counterpart

Awesome. I was using an LSP server for F# (in Sublime Text) on an M2 Mac and it was always running at 500%+ CPU. I had to turn off the LSP server. Hopefully this version fixes it.

Re: Performance Improvements in .NET 7

#72

On the one hand it's cool that they are improving but how do people keep up with all these additions? I find this really hard. Seems a lot of the changes are new stuff which you have to evaluate and see how they could actually be used productively. For example a while ago I tried the new nullable stuff and while in theory it looks straightforward it turned out to be very difficult to use nullable with existing APIs a…

I very much like the ethos of Golang for this reason. Still not had a reason to use it but like the idea of mastering the fundamentals in a weekend. Even if I lose the flexibility of LINQ or Java streams. It feels like a scale of language conservativeness Go all the way at the top, Java somewhat in the middle (a little above) and C# at the bottom. It is going the route with lots of features and complexity, which can…

> C# also made a big mistake imo by going with async/await instead of lightweight threads which will add a ton of complexity in the future for if they decide to go the greenthread route like Goroutines/Project Loom.

Could you expand on this? Async/await is just syntax magic for Task continuations (in other words, Promises [0]), which have very little to do with the underlying threading model. This statement is equivalent to saying "Completable Futures add a ton of complexity to Project Loom."

[0] https://en.wikipedia.org/wiki/Futures_and_promises#List_of_i...

Re: Performance Improvements in .NET 7

#73

Earlier quoted context omitted.

I very much like the ethos of Golang for this reason. Still not had a reason to use it but like the idea of mastering the fundamentals in a weekend. Even if I lose the flexibility of LINQ or Java streams. It feels like a scale of language conservativeness Go all the way at the top, Java somewhat in the middle (a little above) and C# at the bottom. It is going the route with lots of features and complexity, which can…

> C# also made a big mistake imo by going with async/await instead of lightweight threads which will add a ton of complexity in the future for if they decide to go the greenthread route like Goroutines/Project Loom. Could you expand on this? Async/await is just syntax magic for Task continuations (in other words, Promises [0]), which have very little to do with the underlying threading model. This statement is equiva…

IIRC, the statement was from some Java blog about Loom. Idea is that with lightweight threads you can make everything sync and still be performant. While C# has gone ahead with making everything async

Re: Performance Improvements in .NET 7

#74
post #13

I wish benchmarks with sample means in the tens of nanoseconds weren't reported and compared by the arithmetic mean. These are not normal distributions and a 10% improvement could just mean you improved the 99% percentile, which is quite typical in my experience given how skewed the distributions tend to be.

Many of the benchmarks are using BenchmarkDotNet, so consider reporting this to them: https://github.com/dotnet/BenchmarkDotNet/.

Re: Performance Improvements in .NET 7

#75

For people curious how much impact the .NET performance improvements over the last 5 years have on real, large scale web applications: At work we have a core piece of our online ordering system that has been running on .NET Framework 4.8. We run around 8 web servers and handle around 4,000 orders per minute, 300 requests per second per server. We have been working on porting everything over to .NET 6 by making all th…

"Framework" is such a poor differentiator to contrast with modern .NET (owing to the original poor naming decision in the first place--it's not like ".NET" itself is amazing) that it's hard, from a casual reading, to pick up on the fact that "Framework" is even being used a differentiator.

I propose that when people want to differentiate between the modern .NET Core vs the legacy closed source .NET implementation, the latter is referred to as "OG" .NET (in casual and business-casual contexts, at least).

Re: Performance Improvements in .NET 7

#76
post #30

Earlier quoted context omitted.

Can you name other development platforms of similar scale/depth that don’t have this issue? Compared to the whirring treadmill of frontend web development, I find .NET to be pretty easy to keep up with. Good IDEs (ReSharper or Rider) really help with the new language features (which are opt-in). Outside of that, the ecosystem is large enough that there are quality blogs/articles/podcasts to stay current without sinki…

Front end development may have a lot of frameworks, etc., but so much less magic than .Net. What makes .Net so much harder (especially ASP.Net) are the new features but also all the magic that makes discoverability so hard. Front end frameworks tend to follow similar patterns, and where they differ, they usually advertise the difference between the standards heavily. But also, since they are genuinely different frame…

I hear this word all the time “magic”. Can you describe what it means with concrete example for other stacks?

Re: Performance Improvements in .NET 7

#77
post #24

Native AOT will come with .NET 7 https://devblogs.microsoft.com/dotnet/performance_improvemen... > Native AOT is different. It’s an evolution of CoreRT, which itself was an evolution of .NET Native, and it’s entirely free of a JIT. The binary that results from publishing a build is a completely standalone executable in the target platform’s platform-specific file format (e.g. COFF on Windows, ELF on Linux, Mach-O on…

Good. Java is doing something similar with Graal Native Image thing. In a way it is funny to see few years back so many people were claiming that heavy CPU/memory usage of JIT based platforms would be even more non-issue in Cloud because one can scale as much they need on demand. And now I see AOT/Slimmed Runtime/Compact packaging are happening largely because of cloud deployments. Seems cloud bills are making impact…

I do extensive profiling of managed apps and while the JIT does eat a measurable amount of CPU time, it's really not much. And at least on .NET, you can manually ask the runtime to JIT methods, so you can go 'okay, it's startup time, I'm going to spin up a pool of threads and use them to JIT all my code' without blocking execution - for a game I'm working on it takes around 2 seconds to warm ~4000 methods while the other threads are loading textures and compiling shaders. At the end of that the CPU usage isn't a problem and you're mostly dealing with the memory used by your jitcode. I don't know how much of a problem jitcode memory usage actually is in production these days, but I can't imagine it would be that bad unless you're spinning up 64 entirely separate processes to handle work for some reason (in which case I would ask: Why? That's not how managed runtimes are meant to be used.)

I mostly do JIT warming to avoid having 1-5ms pauses on first use of a complex method (which is something that could be addressed via an interpreter + background JIT if warming isn't feasible.)

The slimmed runtime and compact packaging stuff is definitely attractive in terms of faster deploys and lower storage requirements, however, because the cost of needing to deploy 1gb+ worth of stuff to your machines multiple times a day is still a pain. I don't actually know if AOT is an improvement there though, since in some cases the IL that feeds the JIT can be smaller than the AOT output (especially if the AOT compiler is having to pre-generate lots of generic instances that may never get used.) You also have to ship debug information with AOT that the JIT could generate on demand instead.

Re: Performance Improvements in .NET 7

#78
post #33

Unfortunately looks like still no compact strings like Java or JS: https://github.com/dotnet/runtime/issues/6612 You can work around it, but it's nice in languages where common text doesn't take double the memory (because of utf8 or compact strings).

UTF-8 string literals will be part of C# 11/.Net 7, which could help. But they're still more awkward to use than the UTF-16 string.

Re: Performance Improvements in .NET 7

#79

Earlier quoted context omitted.

The "typical" in my comment was meant to take care of that part, I probably should have mentioned this explicitly. AWS Lambda is of course a case where startup time matters a lot, but it still leaves the common problem of ASP.NET that it was designed around a lot of reflection. My understanding is that this simply won't work with AOT out of the box unless you adapt all the places where you use reflection-based code.…

I don't know about ASP.NET, but the post says that Reflection.Emit is not available. Reflection.Emit is a namespace used for runtime code generation; I would assume most other parts of reflection are available, like with previous iterations of AOT support in .NET.

It is theoretically possible to have Reflection.Emit and DynamicMethod for less critical cases by using an interpreter - this happens in certain scenarios already.

Re: Performance Improvements in .NET 7

#80
post #33

Unfortunately looks like still no compact strings like Java or JS: https://github.com/dotnet/runtime/issues/6612 You can work around it, but it's nice in languages where common text doesn't take double the memory (because of utf8 or compact strings).

Is this what you're talking about?

  > "Arguably the biggest improvement around UTF8 in .NET 7 is the new C# 11 support for UTF8 literals."

 > "UTF8 literals enables the compiler to perform the UTF8 encoding into bytes at compile-time. Rather than writing a normal string, e.g. "hello", a developer simply appends the new u8 suffix onto the string literal, e.g. "hello"u8. At that point, this is no longer a string. Rather, the natural type of this expression is a ReadOnlySpan. If you write:"

  > public static ReadOnlySpan Text => "hello"u8;

  > public static ReadOnlySpan Text =>
    new ReadOnlySpan(new byte[] { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o', (byte)'\0' }, 0, 5);
Post reply on HN