This is a detailed answer about how C# compiler optimizes foreach
in the cases when IEnumerator<T>
is a mutable struct.
Does F# compiler perform the same optimization?
f:x↦y means that f is a function which takes in a value x and gives out y.
Remember: The notation "f (x)" is exactly the same thing as "y". You can even label the y-axis on your graphs with "f (x)", if you feel like it.
more ... A special relationship where each input has a single output. It is often written as "f(x)" where x is the input value.
Given a function f, the derivative f' can be used to get important information about f. For instance, f is increasing when f'>0. The second derivative gives useful concavity information.
AFAICT It seems F# treats valuetype enumerators in a similar manner as C#:
Here is a disassembled snippet of IL code from a simple C# program that uses foreach over an IEnumerable<T>
.locals init (
[0] valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>,
[1] int32 v
)
IL_0025: ldloca.s 0
IL_0027: call instance bool valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>::MoveNext()
Note that local 0
is a valuetype and that it uses ldloca.s
to load the address of the struct.
Compare it with F#
.locals init (
[0] class [mscorlib]System.Collections.Generic.List`1<int32> ra,
[1] valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>
)
IL_000e: ldloca.s 1
IL_0010: call instance bool valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>::MoveNext()
This code also uses valuetype to declare local 1
and ldloca.s
to load the address of the struct.
As a side note: Later F# version does actually do an optimization that C# don't do. Because it's a common pattern in F# to iterate over F# lists that are immutable data structures it's ineffective to iterate using enumerators. So F# has a special case for lists and applies a more efficient algorithm in that case. In C# iterating over F# lists would fallback to enumerators.
It would be possible to implement a special handling for IList
types as well but since it's possible someone has implement IList
in a "funny" way it's a potentially breaking change to implement such an optimization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With