[Feature Request] overloads that take a context to avoid lambda capture allocations
A pretty common source of allocations for us is to use something like
var owner = GetOwner();
var best = entries
.Where(e => e.Owner == owner).
.OrderBy(e => owner.GetScore(e))
.FirstOrDefault();
Unfortunately, both examples capture the local scope and allocate every time. One struct linq library I saw was using a context parameter like so:
var owner = GetOwner();
var best = entries
.Where(owner, static (e, context) => e.Owner == context).
.OrderBy(owner, static (e, context) => context.GetScore(e))
.FirstOrDefault();
This is less readable, but gives equivalent performance and allocations as a fully unwrapped version.
Is there any chance of some way to solve this problem being implemented?
There are no plans to add this. I know that such overloads are effective ( Cysharp/R3 adds them to key methods like Where and Select). However, in ZLinq, this would increase the number of types, and there could be a combinatorial explosion with methods that have individual optimizations for subsequent types, making it somewhat difficult to add such overloads.
It is better to make your own ZipRepeat but you can write this way. (I know this workaround is not good for OrderBy)
var best = entries.Zip(ValueEnumerable.Repeat(owner,int.MaxValue))
.Where(static pair => pair.First.Owner == pair.Second)
.OrderBy(static pair => pair.Second.GetScore(pair.First))
.FirstOrDefault().First;
@lgarczyn FWIW .NET 10 teaches the compiler to stack-allocate the closures if it can be proven that the delegate does not escape. Once the release ships, perhaps, it can be investigated which methods in ZLinq need to be aggressively inlined to facilitate this (with careful consideration on the impact it creates on inlining budget, it was increased in .NET 10 but is still a limitation).
@lgarczyn FWIW .NET 10 teaches the compiler to stack-allocate the closures if it can be proven that the delegate does not escape. Once the release ships, perhaps, it can be investigated which methods in ZLinq need to be aggressively inlined to facilitate this (with careful consideration on the impact it creates on inlining budget, it was increased in .NET 10 but is still a limitation).
I understand, though in my case I don't think unity will upgrade to .NET 10 in the next decade ^^