简体   繁体   中英

Performance difference between `is` and `as` in LINQ

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.

OfType Source Code

Benchmark.Net

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM