Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is IEnumerable<T>.Last() optimized for List<T>?

Tags:

c#

.net

c#-4.0

I have a List<T>, called L, containing N items.

Is L.Last(), the IEnumerable<T> extension method, going to run through all N items in linear-time?

Or is it internally optimized to have the constant-time performance of L[L.Count - 1]?

like image 346
Timothy Shields Avatar asked Aug 13 '13 03:08

Timothy Shields


People also ask

Is IEnumerable more efficient than List?

IEnumerable will not execute the query until you enumerate over the data, whereas List will execute the query as soon as it's called. Deferred execution makes IEnumerable faster because it only gets the data when needed. In the code example below, we use LINQ to query the list of numbers.

Which is faster IEnumerable or List?

1) if you iterate elements from IEnumerable or List only one time, so both are same, no differences. 2) if you iterate elements many times, or if you get an one element for multiple times, so, IEnumerable will be slow.

Which is better IEnumerable or List?

IEnumerable is best to query data from in-memory collections like List, Array etc. IEnumerable doesn't support add or remove items from the list. Using IEnumerable we can find out the no of elements in the collection after iterating the collection.

What is difference between IEnumerable and List?

IEnumerable is read-only and List is not. IEnumerable types have a method to get the next item in the collection. It doesn't need the whole collection to be in memory and doesn't know how many items are in it, foreach just keeps getting the next item until it runs out.


1 Answers

You are right, if you take a look the code how to implement Last (from Reflector):

public static TSource Last<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    IList<TSource> list = source as IList<TSource>;
    if (list != null)
    {
        int count = list.Count;
        if (count > 0)
        {
            return list[count - 1];
        }
    }
    else
    {
        using (IEnumerator<TSource> enumerator = source.GetEnumerator())
        {
            if (enumerator.MoveNext())
            {
                TSource current;
                do
                {
                    current = enumerator.Current;
                }
                while (enumerator.MoveNext());
                return current;
            }
        }
    }
    throw Error.NoElements();
}

It actually optimizes for List<T> by returning list[count - 1];

like image 59
cuongle Avatar answered Sep 19 '22 22:09

cuongle