LINQ中`is`和`as`之间的性能差异

Bru*_*ell 2 c# linq performance

我有两个版本的LINQ选择器,它对非泛型类型进行一些过滤并返回一个通用枚举.考虑我们将使用相同的参数完全枚举两者source,我想知道哪个版本的性能更高:

public static IEnumerable<ICollection<TData>> OfType1<TData>(this IEnumerable<ICollection> source) =>
    source
        .Select(c => c as ICollection<TData>)
        .Where(c => !(c is null));

public static IEnumerable<ICollection<TData>> OfType2<TData>(this IEnumerable<ICollection> source) =>
    source
        .Where(c => c is ICollection<TData>)
        .Select(c => c as ICollection<TData>);
Run Code Online (Sandbox Code Playgroud)

在我看来,这一切归结为我们之间的差异is,as因为OfType2我们首先过滤(而不是最后),因此可以减少第二个算子.在第一种情况下,我们需要对可枚举中的所有元素执行两个操作.

那么这里的表现最好呢?引擎盖下如何做isas不同?(链接到源代码欢迎!)

AAA*_*ddd 6

您确实需要自己测试,因为实现可能会发生变化.

但是,您目前的方法有点浪费.OfType将更高效,更直接和更少的分配.

正如您从实现中看到的那样,它只是使用is,yield无论如何,这是您的扩展方法的精神

public static IEnumerable<TResult> OfType<TResult>(this IEnumerable source) {
    if (source == null) throw Error.ArgumentNull("source");
    return OfTypeIterator<TResult>(source);
}
static IEnumerable<TResult> OfTypeIterator<TResult>(IEnumerable source) {
    foreach (object obj in source) {
        if (obj is TResult) yield return (TResult)obj;
    }
}
Run Code Online (Sandbox Code Playgroud)

其他资源

Enumerable.OfType(IEnumerable)方法

根据指定的类型过滤IEnumerable的元素.

OfType源代码

Benchmark.Net