C# LINQ中'is'和'as'的性能差异
我有两个版本的LINQ选择器,它对非泛型类型进行过滤并返回泛型枚举。考虑到我们将用同样的参数枚举这两个参数<代码>源代码>代码>,我想知道哪个版本会更有性能:C# LINQ中'is'和'as'的性能差异,c#,performance,linq,C#,Performance,Linq,我有两个版本的LINQ选择器,它对非泛型类型进行过滤并返回泛型枚举。考虑到我们将用同样的参数枚举这两个参数源代码>代码>,我想知道哪个版本会更有性能: public static IEnumerable<ICollection<TData>> OfType1<TData>(this IEnumerable<ICollection> source) => source .Select(c => c as IColl
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>);
类型1的公共静态IEnumerable(此IEnumerable源)=>
来源
.选择(c=>c作为ICollection)
。其中(c=>!(c为null));
类型2的公共静态IEnumerable(此IEnumerable源)=>
来源
.其中(c=>c是ICollection)
.选择(c=>c作为ICollection);
在我看来,这一切都归结为
is
和as
之间的区别,因为在第2类的中,我们首先过滤(而不是最后过滤),因此可以减少第二个操作符的工作量。在第一种情况下,我们需要对枚举表中的所有元素执行这两种操作
那么,在这里,什么才是真正表现最好的呢?发动机罩下的和有什么区别?(欢迎链接到源代码!)
由于实现可能会发生变化,您确实需要自己进行测试
然而,您当前的方法有点浪费<类型为
的代码>将更高效、更直接、分配更少
从实现中可以看出,它只是使用了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;
}
}
类型的公共静态IEnumerable(此IEnumerable源){
if(source==null)抛出错误.ArgumentNull(“source”);
返回类型迭代器(源);
}
类型迭代器的静态IEnumerable(IEnumerable源){
foreach(源中的对象obj){
如果(obj为TResult)收益率回报(TResult)obj;
}
}
其他资源 根据指定类型筛选IEnumerable的元素
为什么不在数据上衡量自己呢?
是
和,因为
加起来基本上是两种类型,所以我猜第二种版本会慢一些。然而,您应该总是简单地尝试一下,然后看看。为什么不直接使用Linq的of type
source.OfType().ToList()
?与=>source.OfType()相比,两者似乎同样低效且毫无意义代码>。LINQ通常比常规循环慢几倍,与实现可以更改相比,as
/的差异非常小。@abatishchev这是对框架和clr的参考,主要的一点是,您只需自己测试这些东西,因为性能差异和优化在未来可能会有所不同(通常)