Live data from Hacker News

Performance Improvements in .NET 10

devblogs.microsoft.com

51–60 of 98 posts

Re: Performance Improvements in .NET 10

#52
post #31

Earlier quoted context omitted.

This hasn't been an issue for a long time because nobody uses the non-generic collections anymore. That doesn't help you with your reliance on type erasure though. If you're up for it you should give it another try. Your example of subclassing GenericType and GenericType may be supported with covariance and contravariance in generics [1]. It's probably not very well known among C# developers (vs. basic generics) but…

Yeah, I had a chance a few months back when I was the backup programmer in a game development hackathon and my team was developing with Unity which uses C#. It was fun. People talk about tradeoffs with GC, the worst one is that I've seen an occasional game that has a terrible GC pause, for instance Dome Keeper based on Godot which also runs in .NET. I used play a lot of PhyreEngine (also .NET) games on the Playstatio…

PhyreEngine doesn't use .NET, and it is written in C++ (with optional Lua for scripting). You might be thinking of PlayStation Mobile, which does use .NET for scripting.

Re: Performance Improvements in .NET 10

#53
post #3

If only they could fix the ecosystem's stability; I feel like anything written with C#'s staple packages becomes outdated considerably faster than any other options.

Yep. A breaking change that makes my code a gajillion times faster is still always just a dirty breaking change that I'll hate.

They almost never make any breaking changes these days. And when they do it's because of something that is absolutely unavoidable. I've never hit one.

Re: Performance Improvements in .NET 10

#54

This kinda stuff brings languages like C# and Java closer to Rust in performance, thinking like the "borrow checker" it understands the scope of some objects and puts them on the stack and avoids garbage collection and allocation overhead. It keeps the unsung benefit of garbage collection for "programming in the large" in which memory allocation is treated as a global concern independent of everything else instead of…

This is wishful thinking. It’s the same as other layers we have like auto-vectorization where you don’t know if it’s working without performance analysis. The complexity compounds and reasoning about performance gets harder because the interactions get more complex with abstractions like these. Also, the more I work with this stuff the more I think trying to avoid memory management is foolish. You end up having to th…

> It’s the same as other layers we have like auto-vectorization where you don’t know if it’s working without performance analysis. The complexity compounds and reasoning about performance gets harder because the interactions get more complex with abstractions like these.

Reasoning about performance is hard as it is, given nondeterministic optimisations by the CPU. Furthermore, a program that's optimal for one implementation of an Aarch64 architecture can be far from optimal for a different implementation of the same architecture. Because of that, reasoning deeply about micro-optimisations can be counterproductive, as your analysis today could be outdated tomorrow (or on a different vendor's chip). Full low-level control is helpful when you have full knowledge of the exact environment, including hardware details, and may be harmful otherwise.

What is meant by "performance" is also subjective. Improving average performance and improving worst-case performance are not the same thing. Also, improving the performance of the most efficient program possible and improving the performance of the program you are likely to write given your budget aren't the same thing.

For example, it may be the case that using a low-level language would yield a faster program given virtually unlimited resources, yet a higher-level language with less deterministic optimisation would yield a faster program if you have a more limited budget. Put another way, it may be cheaper to get to 100% of the maximal possible performance in language A, but cheaper to get to 97% with language B. If you don't need more than 97%, language B is the "faster language" from your perspective, as the programs you can actually afford to write will be faster.

> Also, the more I work with this stuff the more I think trying to avoid memory management is foolish.

It's not about avoiding thinking about memory management but about finding good memory management algorithms for your target definition of "good". Tracing garbage collectors offer a set of very attractive algorithms that aren't always easy to match (when it comes to throughput, at least, and in some situations even latency) and offer a knowb that allows you to trade footprint for speed. More manual memory management, as well as refcounting collectors often tend to miss the sweet spot, as they have a tendency for optimising for footprint over throughput. See this great talk about the RAM/CPU tradeoff - https://youtu.be/mLNFVNXbw7I from this year's ISMM (International Symposium on Memory Management); it focuses on tracing collectors, but the point applies to all memory management solutions.

> Should have noted that Zig solves this by making the convention be to pass an allocator in to any function that allocates. So the boundaries/responsibilities become very clear.

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.

Re: Performance Improvements in .NET 10

#55
post #19

Earlier quoted context omitted.

lol, whut? Microsoft created the ".NET Standard" for this. Literally anything that targets .NET Standard 1.0 should work from circa 2001 through modern day 2025. You still get the (perf) benefits up the runtime upgrade which is what the blog post is about.

.NET Standard is more for maintaining interoperability between .NET Framework and .NET (Core). At this point only (very) legacy applications should be on Framework. Everything else isn't, so they shouldn't use. NET Standard as a target because it limits the new features they can use.

I support your statement for custom dev applications. Unfortunately some large enterprise applications like D365 still require the Framework :(.

Re: Performance Improvements in .NET 10

#56
post #3

If only they could fix the ecosystem's stability; I feel like anything written with C#'s staple packages becomes outdated considerably faster than any other options.

If you are not on the bleeding edge of whatever new framework Microsoft is promoting today, the ecosystem is incredibly stable.

Re: Performance Improvements in .NET 10

#57
post #29

Earlier quoted context omitted.

In my company running maybe 20K servers on .NET, we get a 10-20% CPU decrease every time we upgrade to the next major.

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.

Re: Performance Improvements in .NET 10

#58

Earlier quoted context omitted.

Yep. A breaking change that makes my code a gajillion times faster is still always just a dirty breaking change that I'll hate.

The breaking changes are very well documented and are esoteric in nature. https://learn.microsoft.com/en-us/dotnet/core/compatibility/... Scott Hanselman has a very short blog on how 20 year old code is upgraded to the latest .NET in just a few short minutes: https://www.hanselman.com/blog/upgrading-a-20-year-old-unive...

Bs, basically, the docs about upgrading between frameworks and what works with what is actually pretty current and often disappears after some years. Especially anything about edge cases. Several upgrades also demands that you do the upgrade version by version. It is tedious work if you don't have a full understanding of the app. Nuget has also become a complete dependency hell. Today you often have to point out what to use to get your legacy apps to build with newer .NET versions. You can't just go with latest.

Re: Performance Improvements in .NET 10

#59

Earlier quoted context omitted.

> thinking like the "borrow checker" it understands the scope of some objects and puts them on the stack and avoids garbage collection and allocation overhead. On the other side however if you don't write code that the borrow checker would accept you likely won't get these optimizations. And even if it was accepted there's a chance the analysis needs to be too deep or complex for the escape analysis to work. Ultimate…

The counter to that is that is that performance really matters in inner loops and in those cases the hot area is not that big, it doesn’t matter if your setup and tear down give up a lot of possible performance. Early this year my son was playing chess which motivated me to write a chess program. I wrote one in Python really quickly that could challenge him. I was thinking of writing one I could bring to the chess cl…

I guess you could to now try some realtime audio processing. Surprisingly (to me) there are actuall existing realtime DSP packages for Java.

Re: Performance Improvements in .NET 10

#60

This reads like one of those recipe blogs where you first need to hear about great grandpappy's migration during the potato famine before you can get to the details on how to make cupcakes. First 5 paragraphs are just noise.

Try to imagine the hours going into a post like this.

These posts are among the very best, digging into details explaining why things work and why changes were made.

Every time they get released I'm happy because no one killed it...

Post reply on HN