score:2
My guess, which is a shot in dark, as any answer you might get: optimizing in the predicate case would cause more side effects. Optimization generally causes a side-effect because the GetEnumerator() of IEnumarble is not called. But in the predicate case, you can observe from the outside that it's not called in order. One might write a predicate that expects the iteration to happen in order, and going backwards would break that.
score:0
Except when an implementation of IList<T>
contains a very small number of items, optimizing the non-predicate Last
to return theList[theList.Count()-1]
is unlikely to be slower than simply enumerating from the start; it's unlikely that for any reasonable IList<T>
implementation it will be much slower. Even though the time required for some implementations of IList<T>
to find an item by index may be significantly longer than the average per-item time required to fetch data sequentially (perhaps by an order of magnitude, though probably not two), reading one item by index will generally take much less time than reading every item sequentially (random access generally won't be much slower than sequential access unless a collection is big; if in a 1,000,000-item collection the cost to read an item by index is 1,000 times the per-item time required for sequential access [an atypically-large penalty], that would still be 1,000 times as fast as reading every item).
When using Last
with a predicate, there's no guarantee how many items will need to be examined. If random access takes longer than sequential access (common), and the last match happens to occur early in the list (highly plausible), then processing the list from the start will be faster than processing from the end. Given that it would not be unreasonable for an IList<T>
implementation to take ten times as long to perform a random access as a sequential fetch, the "optimization" of reading from the back could end up making things an order of magnitude slower than "unoptimized" code that read sequentially.
If IList<T>
provided more options for reading out data, and/or included properties which roughly described the relative costs of different operations, then a Last
method could be optimized to examine list items in some other sequence, but absent such features it's better for the method to use a straightforward approach whose behavior is predictable if uninspiring, than one which tries to be clever but might sometimes perform much worse.
Source: stackoverflow.com
Related Articles
- Unoptimized IEnumerable<>.Last with predicate
- IEnumerable to string delimited with commas?
- What does this C# code with an "arrow" mean and how is it called?
- Drop the last item with LINQ
- IEnumerable<T>.Contains with predicate
- IEnumerable cannot be used with type arguments
- Is there an IEnumerable implementation that only iterates over it's source (e.g. LINQ) once?
- Comma separated list with "and" in place of the last comma
- How to load just the last record from entity with LINQ?
- get last element with linq to sql
- Select from IEnumerable with Distinct/GroupBy and sorting — possible?
- Using Lambda Expressions trees with IEnumerable
- Exclude types form IEnumerable with linq
- Dynamically cast IEnumerable to IQueryable or dynamically call AsQueryable with LINQ Expressions
- Why doesn't this code compile in VS2010 with .NET 4.0?
- How do I convert IEnumerable to Collection with linq
- Splice IEnumerable with Linq
- Method with Predicate as Parameter
- When will connection be closed in case of IEnumerable with using
- How to Zip one IEnumerable with itself
- Why is this code with PredicateBuilder not working?
- How to skip last 2 records and get all other records with linq?
- Create predicate with nested classes with Expression
- Can you advise me a resource with LINQ/lambda code exercises?
- Get request to api with predicate expression as a parameter
- LINQ Source Code Available
- Split IEnumerable in three parts: "above", "item", "below" with efficiency
- LINQ: is there a way to supply a predicate with more than one parameter to where clause
- How to properly integration test Web Api controller with IEnumerable results?
- Dynamic Linq Predicate throws "Unsupported Filter" error with C# MongoDB Driver
- How to query DataSets using LINQ and ouput in JSON format
- LINQ join: Collection that has no data or null
- Simple Linq query that joins two tables and returns a collection
- Linq To DataSet getting error
- Using LINQ to loop through inner class properties in outer class collection and group by outer class properties
- convert Dictionary<string, myClass> to List<double[]> using c# linq
- Creating sub lists with objects of the same attribute from a list using LINQ
- Migrating from EF Core 2 to EF Core 3
- Lambda Expression if-else statement in where clauses
- Change binding at runtime to a particular element of a list based off property of the list item
- What is the best way to optimize or "tune" LINQ expressions?
- Binding a flattern EF entity over GridView and allow sync with repositories
- Sorting Array based on property of object on inner array
- LINQ dynamic expression with string join
- Adding to the Where clause of an Update in LinQ-to-Entities
- Convert my SQL to LINQ
- How to sort an element as you add it to a list?
- Linq: Selecting a new List<Guid> in C#
- Looping through unknown amount of lists that are in a list in C#
- The translation of String.IndexOf to SQL does not support versions with a StringComparison argument