I have two versions of a LINQ selector which does some filtering of non-generic types and returns a generic enumeration. Consider we will fully enumerate both with the same parameter source
, I wonder what version will be more performant:
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>);
In my believe it all boils down to the difference between is
and as
since in OfType2
we filter first (not last) and thus can possible do less of the second operator. In the first case, we need to do both operations on all elements in the enumerable.
So what actually does perform best here? And how do is
and as
differ under the hood? (Links to source code welcome!)
You really need to test this yourself as implementations may change.
However, your current approach is a bit wasteful. OfType
will be more performant, more direct and less allocations.
As you can see from the implementation it is just using is
and yield
which is kind of the spirit of your extension method anyway
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;
}
}
Additional Resources
Enumerable.OfType(IEnumerable) Method
Filters the elements of an IEnumerable based on a specified type.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.