-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make it possible to omit memory allocation for closures #18
Comments
Thank you for your proposal. This is interesting idea- I have two concerns about it.
array.Gen(context1, context2)
.Where(static (x, c1, _) => x < c1)
.Select(static (x, _, c2) => x + c2) Ofc, this can be bypassed if we pass context to each query instead. array.Gen()
.Where(context1, static (x, c1) => x < c1)
.Select(context2, static (x, c2) => x + c2)
struct LimitPredicate : IStructFunction<int, bool>
{
private int _limit;
public Predicate(int limit) => _limit = limit;
public bool Invoke(int value) => value < _limit;
}
int result = array.Gen()
.Where(new LimitPredicate(upperLimit))
.Sum(); This way, we can pass context and enable inlining via value type generic specialization. |
Thank you for considering my idea! I have a few comments about the concerns.
array.Gen((context1, context2))
.Where(static (x, tuple) => x < tuple.context1)
.Select(static (x, tuple) => x + tuple.context2) Also, it would be nice to have an overload accepting a delegate without the second argument: array.Gen((context1, context2))
.Where(static (x, tuple) => x < tuple.context1)
.Select(static (x, tuple) => x + tuple.context2)
.Select(static x => x + 5)
|
After I wrote the previous comment, I understood that there is another concern - we already have an overload of the
I assume that if you pass the "context argument" to the |
I implemented similar functionality in my async linq. You can pass a capture value to each query. Basically you just pass an extra value right before the delegate, and include that value as the first argument to the delegate. I think you could do the same here. It should be very easy to translate it to array.Gen()
.Where(context1, static (c1, x) => x < c1)
.Select(context2, static (c2, x) => x + c2)
.Select(static x => x + 5) |
Problem
Consider the following code
A new instance of a compiler-generated class will be created each time this code executes to store closure values (
upperLimit
in this case). We could omit an allocation if we pass theupperLimit
variable to the predicate. For example, GetOrAdd method of a concurrent dictionary has afactoryArgument
parameter to achieve the same improvement.Proposed solution
Add an overload for the
Gen
method with an argument representing the state needed for delegates. Then, the previous code can be replaced with theThe text was updated successfully, but these errors were encountered: