Live data from Hacker News

Performance Improvements in .NET 10

devblogs.microsoft.com

71–80 of 98 posts

Re: Performance Improvements in .NET 10

#71
post #41
post #26

Earlier quoted context omitted.

I've hedged the stability risk by using the narrowest possible slice of the framework. With enough experience you can accomplish pretty much everything using just the minimal API and router. HttpContext is the heart of AspNetCore. If you can get your hands on instances of it within the appropriate application context, you can do anything you need to. Everything else is dependent upon this. The chances that HttpContex…

do you still use the framework's DI pattern with this approach? I have an older school .NET app I work on (still Core) sometimes and haven't gotten much experience with the minimal APIs, although it looks attractive as someone that prefers lower level routers.

I use the AddService() method to inject a things on occasion but its not used heavily. For lightweight apps I'll spin up things like a shared SQLiteConnection and inject it for all resources to use.

The DI pattern is simple & clean at this scale. In my top-level program I define my routes like:

  app.Map("/", Home.HandleRequest);
  app.Map("/login", Login.HandleRequest);
  app.Map("/account/new", NewAccount.HandleRequest);
  app.Map("/{owner}", OwnerHome.HandleRequest);
And then I have HandleRequest implementations like:

  static async Task HandleRequest(HttpContext context, SQLiteConnection sql)
  static async Task HandleRequest(HttpContext context, SQLiteConnection sql, string owner)
  etc...
The actual HandleRequest() method can do anything, including concerns like directly accepting and handling web socket connections.

Re: Performance Improvements in .NET 10

#72

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…

I really liked reading this article: Writing high performance F# code https://www.bartoszsypytkowski.com/writing-high-performance-...

It more or less tells you to unlearn all functional and OOP patterns for code that needs to be fast. Just use regular loops, structs and mutable variables.

Re: Performance Improvements in .NET 10

#73

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…

Efficient memory allocation is part of a well written designed API.

Languages like C++ give you a tonne of options here, from passing in scratch buffers to libraries, passing in reusable containers, move semantics, to type erased primitives like std::memory_resource and std::shared_ptr

Re: Performance Improvements in .NET 10

#74
post #68

Earlier quoted context omitted.

Even way back when: https://devblogs.microsoft.com/oldnewthing/20060731-15/?p=30... > The fact that Rico Mariani was able to do a literal translation of the original C++ version into C# and blow the socks off it is a testament to the power and performance of managed code. It took me several days of painful optimization to catch up, including one optimization that introduced a bug, and then Rico simply had to do a lit…

Unrelated, but Microsoft should be ashamed that most of the links in that blog no longer work.

I was actually surprised much of the material still exists - though the links don't work. Microsoft performs so much needless self-vandalism and I know some things I care about are gone.

Which just reminded that yeah, all the links I'd made to Raymond Chen's "The poor man's way of identifying memory leaks" no longer work. The Rust implementation is less than four years old, but its link (which worked) now does not. -sigh-

Tempting to go reconstruct that performance improvement "fight" in Rust too. Maybe another day.

Re: Performance Improvements in .NET 10

#75

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.

The first five paragraphs tell a very relevant story to drive a key point home: performance is often about many small things shaved down, not one giant silver bullet.

I’ve lost count of the number of times I’ve seen customers immediately “double down” on the size of their servers as a quick fix… and achieving nothing other than increasing their cloud provider’s revenue.

Performance comes from a long series of individually small fixes.

Re: Performance Improvements in .NET 10

#76
post #73

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…

Efficient memory allocation is part of a well written designed API. Languages like C++ give you a tonne of options here, from passing in scratch buffers to libraries, passing in reusable containers, move semantics, to type erased primitives like std::memory_resource and std::shared_ptr

Perhaps rather than "a tonne of options" people might like to have fewer that are actually good ?

Re: Performance Improvements in .NET 10

#77
post #66

Earlier quoted context omitted.

GC is problematic for cross-language foundational libraries though (unless they run on the same VM of course).

Makes me wonder how easy/hard it is to write a library in Rust and expose it to other languages.

One extreme case of this would be rustls-openssl-compat which is basically what if you take a Rust TLS implementation but you give it the same ABI as the openssl C library so (where this works, which is far from everywhere) it's a drop-in replacement.

e.g. you can run curl, and go fetch https://example.com/ but using this ersatz openssl rather than your C openssl implementation. That's a thing which works today, albeit not a supported configuration from the point of view of Curl's author.

Re: Performance Improvements in .NET 10

#78
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…

Whether you're programming with a GC or without one it all comes down to profiling and optimization (when required). Using a GC means you need to think about memory allocations and reduce them (when required) because they factor into how long the GC will need to run. C# is a great language for this because it provides a lot of options for removing GC memory allocations from your code entirely (struct types, Span, etc).

Not all GCs are created equally either. Unity, for example, is based on an ancient version of Mono and so it uses the Boehm GC which is significantly slower than the one used by .NET. Godot probably has two GCs because it primarily runs GDScript (their custom language) and only supports using .NET in a separate engine build. They'll all have their own performance characteristics that the developer will need to adjust for.

Re: Performance Improvements in .NET 10

#80

Earlier quoted context omitted.

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…

"Several upgrades also demands that you do the upgrade version by version"

This seems unlikely. Do you have a source?

Post reply on HN