Replies: 1 comment 3 replies
-
The compiler doesn't make any attempt to decide if a lambda is trivial enough to be replaced by something else, e.g. replacing |
Beta Was this translation helpful? Give feedback.
3 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
In a LINQ expression like this:
The code that gets generated looks a little like this:
The second lambda in
SelectMany
is unnecessary when there's aSelectMany(M<A>, Func<A, M<B>>)
available (whereM
is the type that has aSelectMany
implementation, likeIEnumerable
).If you look at the generated IL for the second lambda, all it does is return the second argument:
The generated code could easily be:
Because there's no additional processing after the final
from
clause, the projection function is simply an identity mapping. However an additional allocation is still needed (for theFunc
) and about 10 extra lines of IL are needed to invoke it (when it does nothing).I always understood that the compiler would pick the best
SelectMany
implementation if we provided them.So, either:
SelectMany
SelectMany
that I am not doing.It would seem to me to be a relatively trivial optimisation and would reduce the allocation overhead of a common pattern in LINQ (and be more CPU efficient).
I wonder, does anyone have any insight in to this?
One final thing on this (and the real reason I am asking). I am adding
Transducers
to my language-ext project; they are going to be the system that backs all of the monadic types, likeTry<A>
,Eff<A>
,Option<A>
,Reader<E, A>
, etc.I have found a way to make transducers support infinite recursion without blowing the stack. Below is an example of an infinite recursive loop.
Except because of the picking of
SelectMany(M<A>, Func<A, M<B>>, Func<A, B, C>)
rather thanSelectMany(M<A>, Func<A, M<B>>)
it ends up with a space leak.If I write the code above as:
Then I get infinite recursion without the space leak, which is pretty massive for a functional programming technique in C#.
I am about to start looking at building a Fody plugin to try and solve this, but really it would be great if the compiler didn't do work it didn't need to do and in the process cause me a space leak! ;)
Beta Was this translation helpful? Give feedback.
All reactions