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

时间:2018-12-23 23:31:00

标签: c# performance linq

我有两个版本的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>);

我认为这全都归结为isas之间的差异,因为在OfType2中,我们首先过滤(而不是最后过滤),因此可以减少第二个运算符的数量。在第一种情况下,我们需要对可枚举中的所有元素执行两项操作。

那么,在这里实际效果最好的是什么? isas到底有什么不同? (欢迎链接到源代码!)

1 个答案:

答案 0 :(得分:6)

由于实现可能会发生变化,因此您确实需要自己进行测试。

但是,您当前的方法有点浪费。 OfType的性能更高,更直接,分配更少。

从实现中可以看到,它只是使用isyield,这仍然是扩展方法的精神

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;
    }
}

其他资源

Enumerable.OfType(IEnumerable) Method

  

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

OfType Source Code

Benchmark.Net