Dies ist ein Follow-up zu meinem vorherigen question in Bezug auf die iter
des Seq
Modul und map
Funktionen langsamer sind viel im Vergleich zu dem Array
und List
Modul-Äquivalente.Warum sind einige Funktionen im Seq-Modul optimiert, während andere nicht in F # waren?
an der Quelle der Suche, kann ich sehen, dass einige Funktionen wie isEmpty
und length
eine sehr einfache Art Prüfung durchführt, um für Arrays und Listen zu optimieren, bevor greifen IEnumerator
verwenden.
[<CompiledName("IsEmpty")>]
let isEmpty (source : seq<'T>) =
checkNonNull "source" source
match source with
| :? ('T[]) as a -> a.Length = 0
| :? list<'T> as a -> a.IsEmpty
| :? ICollection<'T> as a -> a.Count = 0
| _ ->
use ie = source.GetEnumerator()
not (ie.MoveNext())
[<CompiledName("Length")>]
let length (source : seq<'T>) =
checkNonNull "source" source
match source with
| :? ('T[]) as a -> a.Length
| :? ('T list) as a -> a.Length
| :? ICollection<'T> as a -> a.Count
| _ ->
use e = source.GetEnumerator()
let mutable state = 0
while e.MoveNext() do
state <- state + 1;
state
Im Fall der iter
der gleiche Ansatz in beträchtlichem Ausmaß getan werden kann, um seine Leistung zu verbessern, wenn ich die iter
Funktion es, erhebliche Gewinne über die integrierte Version shadowed:
[<CompiledName("Iterate")>]
let iter f (source : seq<'T>) =
checkNonNull "source" source
use e = source.GetEnumerator()
while e.MoveNext() do
f e.Current;
Mein Die Frage ist, dass einige der Funktionen im Seq
Modul für die Verwendung mit bestimmten Sammlungstypen (Arrays, Liste < T> usw.) optimiert wurden, wie andere Funktionen wie iter
und nth
nicht op waren ähnlich timized?
Auch im Fall von map
Funktion, wie @mausch darauf hingewiesen, ist es nicht möglich, einen ähnlichen Ansatz zu Enumerable.Select
(siehe unten) und bauen spezielle Iteratoren für verschiedene Sammlungstypen zu verwenden?
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
{
if (source == null)
throw Error.ArgumentNull("source");
if (selector == null)
throw Error.ArgumentNull("selector");
if (source is Enumerable.Iterator<TSource>)
return ((Enumerable.Iterator<TSource>) source).Select<TResult>(selector);
if (source is TSource[])
return (IEnumerable<TResult>) new Enumerable.WhereSelectArrayIterator<TSource, TResult>((TSource[]) source, (Func<TSource, bool>) null, selector);
if (source is List<TSource>)
return (IEnumerable<TResult>) new Enumerable.WhereSelectListIterator<TSource, TResult>((List<TSource>) source, (Func<TSource, bool>) null, selector);
else
return (IEnumerable<TResult>) new Enumerable.WhereSelectEnumerableIterator<TSource, TResult>(source, (Func<TSource, bool>) null, selector);
}
Vielen Dank im Voraus.
Ich bin mir nicht sicher, ob Sie hier eine vernünftige Antwort auf eine "Warum" -Frage erhalten werden; Mein bestes _guess_ ist einfach Mangel an Entwicklerzeit. – ildjarn