Disable LINQ optimization for custom IList implementation

c# ilist
c# ilist implementations
ilist vs ienumerable
linq where implementation
c# list
icollection
c# ilist<t>
ienumerable vs list which is faster

LINQ's methods Select, Where, SelectMany (maybe others, not sure) use optimized implementation if provided collection implements IList<T> interface - it does not use GetEnumerator method, but retrieves elements by index instead (at least in dotnet core, to avoid using enumerator overhead, I suppose).

Is there any way to disable that optimization for certain type?

I have IList implementation, which proxies all calls to another collection, therefore iterating all elements using enumerator is actually much faster, than getting all elements by index.

Of course you can. Implement the given methods specifically for your type. You can provide your type specific implementations either as extension methods or as instance methods and the compiler will choose them since they are more specific (naturally extension-methods will need to be in scope in order to be considered).

An example of type specific optimizations of LINQ methods can be found targeting System.Collections.Immutable.ImmutableArray<T>.

Edulinq, The main thrust was going to be that the implementation of LINQ is simple, and it's If you're building an API which benefits from small pieces of custom behaviour, Just as LINQ to Objects is primarily interested in IEnumerable<T> and the Reimplementing LINQ to Objects: Part 42 – More optimization. Forget the theory and just try to lean LINQ directly by programming. Believe me, after few examples you will feel that you are very familiar with LINQ. Example 1: Create IList and store Product Name and Price and then display value using LINQ Query.

Optimisations in LINQ to Objects, While many implemenations of ICollection<T> will also implement ICollection (​including NET 4.0 it does optimise for ICollection as well. once when I write a custom LINQ operator – you never know when you'll be given a  Some methods (like SkipLast) try to cast their IEnumerable input parameters to an ICollection or an IList for optimization purpose. But some methods, like CountBy returns an IEnumerable even if they internally have build the full sequenc

My advice would be to create an IEnumerable extension function that takes an input sequence, and returns the same sequence as an IEnumerable.

See Extension Methods Demystified

public static IEnumerable<TSource> ToEnumerable (this IEnumerable<TSource> source)
{
     foreach (var sourceItem in source)
         yield return sourceItem
}

Usage:

List<Person> persons = ...

var personList = persons.ToList(); // uses the fact that Persons implements IList

var otherList = persons.ToEnumerable().ToList();
// does not implement IList<...>, and thus doesn't use the optimization

IList Interface (System.Collections), Data.Linq.EntitySet<TEntity> · System.Data.SqlClient.SqlParameterCollection The following example demonstrates the implementation of the IList interface to create a simple, fixed-size list. WriteLine("Remove elements from the list"); test. Implementing a custom LINQ provider. Jan 28, 2010. I recently read an interesting article that describes how the LINQ to SQL provider was implemented. The article gave a pretty good description of expression trees and how they relate to IQueryable and LINQ.

How C# IEnumerable Can Kill Your Site's Performance, For example, look at the declaration of the IList<T> interface. public interface IList​<T> : ICollection<T>, IEnumerable<T>, IEnumerable. IList<T> implements  LINQ's methods Select, Where, SelectMany (maybe others, not sure) use optimized implementation if provided collection implements IList<T> interface - it does not use GetEnumerator method, but

C# List<T>, Exception Handling · throw · Custom Exception · C# - Delegates The List<T> is a concreate implementation of IList<T> interface. Remove, Removes the first occurence of the specified element. LINQ can be use to query List<T> collection. TutorialsTeacher.com is optimized for learning web technologies step by step. As outlined by Joe Duffy, LINQ introduces inefficiencies in the form of hidden allocations, from The ‘premature optimization is evil’ myth: To take an example of a technology that I am quite supportive of, but that makes writing inefficient code very easy, let’s look at LINQ-to-Objects.

Collection in C#, The Queue and Stack collection implement ICollection inferface. IList: The IList interface includes properties and methods to add, insert, remove elements in the collection and The ArrayList and BitArray collections implement IList interface. TutorialsTeacher.com is optimized for learning web technologies step by step. As outlined by Joe Duffy, LINQ introduces inefficiencies in the form of hidden allocations, from The ‘premature optimization is evil’ myth: To take an example of a technology that I am quite supportive of, but that makes writing inefficient code very easy, let’s look at LINQ-to-Objects.

Comments
  • therefore iterating all elements using enumerator is actually much faster, than getting all elements by index. which collection supports that behavior?
  • The methods Select, Where, SelectMany don't have this kind of optimization, only methods that provide access to elements by index or return the Count, like ElementAt or Count, have.
  • Also, why you implement IList at all if's better to not access it via index?
  • The problem in this case is that you use the wrong interface, thus breaking its contract. Implement IEnumerable if you can't support IList<T>'s semantics. It's not LINQ's optimizations that cause problems here, everyone who's going to use that class through the IList<T> interface will suffer
  • Can you please show your implementation of the IList or provide some code which reproduces your problem? It's hard to understand why enumerating all items is faster than getting them by index
  • Yeah, but that would only work if I know the type at runtime. In my case the actual type is internal, and I only work with IList<T>. I'm thinking about creating extension methods for general IList<T>, and check for actual type there.
  • 1. Nope, Select, SelectMany etc wont use an enumerator, at least in dotnet core. Take a look: Select SelectIListIterator (line 256)
  • Therefore option 1 won't help. I can, however, wrap it into something like that foreach(var e in elements) ` yield return e;`