Remix.run Logo
yread 2 days ago

Amazing progress, some LINQ constructions were made 300 times faster. But reasoning over what code does heap allocations is getting more and more complicated. I guess intuition has to give even more way to benchmarking

kg 2 days ago | parent | next [-]

(Disclosure: I get paid to work on .NET)

The good thing is that the older techniques to minimize allocations still work, and tools like refs and ref structs make it easier to write zero-allocation code than it used to be.

But it's definitely harder to reason about whether optimizations will 'light up' for code that uses heap-allocated classes, closures, etc. than it was in the past, even if it's harder for a nice reason.

BenchmarkDotNet is a fantastic piece of tech at least, I have found it easier to benchmark in C# than in most other ecosystems I work with.

jsmith45 a day ago | parent | prev [-]

My view, which I suspect even Toub would agree with is that if being allocation free or even just extremely low allocation is critical to you, then go ahead and use structure and stackalloc, etc that guarentee no allocations.

It is far more guarenteed that that will work in all circumstances than these JIT optimizations, which could have some edge cases where they won't function as expected. If stopwatch allocations were a major concern (as opposed to just feeling like a possible perf bottleneck) then a modern ValueStopwatch struct that consists of two longs (accumulatedDuration, and startTimestamp, which if non-zero means the watch is running) plus calling into the stopwatch static methods is still simple and unambiguous.

But in cases where being low/no allocation is less critical, but your are still concerned about the impacts of the allocations, then these sort of optimizations certainly do help. Plus they even help when you don't really care about allocations, just raw perf, since the optimizations improve raw performance too.