the*_*onk 8 collections performance f#
这是我之前关于模块和函数与模块等效项相比要慢得多的问题的后续内容.SeqitermapArrayList
查看源代码,我可以看到一些函数,例如isEmpty和length执行非常简单的类型检查,以便在使用之前优化数组和列表IEnumerator.
[<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
Run Code Online (Sandbox Code Playgroud)
在采用iter相同的方法可以大大提高其性能的情况下,当我对该函数进行阴影处理时,iter它比内置版本显着提升:
[<CompiledName("Iterate")>]
let iter f (source : seq<'T>) =
checkNonNull "source" source
use e = source.GetEnumerator()
while e.MoveNext() do
f e.Current;
Run Code Online (Sandbox Code Playgroud)
我的问题是,因为一些在功能Seq模块被用于与特定集合类型使用优化的(阵列,列表<T>等)如何来其他功能,例如iter和nth以类似的方式未优化?
另外,在map函数的情况下,正如@mausch指出的那样,是否不可能采用类似的方法Enumerable.Select(见下文)并为不同的集合类型构建专门的迭代器?
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);
}
Run Code Online (Sandbox Code Playgroud)
提前谢谢了.
Seq.length从表面上看, /中的类型检查isEmpty似乎是错误。我假设大多数Seq函数不执行此类正交性检查:List/Array模块中已存在特定于类型的版本。为什么要重复它们?
这些检查在 LINQ 中更有意义,因为它只IEnumerable直接使用。
| 归档时间: |
|
| 查看次数: |
334 次 |
| 最近记录: |