实现自己的LINQ和IEnumerable

在我正在开发的项目中,有非常庞大的集合(1M-1B元素),并且事物大部分被修改为集合。

这是一个实时应用程序,因此性能至关重要。

对于某些操作,如Reverse,BinarySearch(可能的?)等会比Select等更多的操作受到影响。

是否可以使用可能的MoveNext,MovePrev等实现自己的IEnumerable,并拥有利用这些优势的已实现的LINQ扩展?

如果发生这种情况,它将在项目结束时发生。 因为我们需要先让它工作,然后加快速度。

总而言之,这不应该是太多的工作,对吧?

绝对可以创建自己的Enumerable实现,这可能是特殊情况下的某些情况。 您基本上想要检测自己的集合类型(或者可能只是集合,如List ),并在适用的情况下使用更高效的实现。

我有一个示例项目 ,我用它来演示“在一小时内实现LINQ to Objects”,您可能希望查看这些示例。 它不是一个完整的实现,特别是它的效率低于真正的LINQ to Objects – 但你可能仍然觉得它很有趣。

或者,您可能会发现i4o(索引LINQ)可以开箱即用 – 或者您最好从头开始做出贡献。 值得一试。

请记住,在一天结束时,LINQ基本上是一个很好的设计加上语法糖。 例如,C#编译器对System.Linq.Enumerable一无所知。

如果你真的想要表现,你可以做很多事情。 请记住以下选择:

 var result = from element in collection where element.Id == id select element; 

编译为:

 var result = collection.Where(element => element.Id == id); 

如果为collection类型创建以下方法,则可以利用主要操作与Id成员相等的事实,并以优化的方式处理请求。 重要的是正确识别集合中的性能关键操作,并选择正确的算法(即复杂性)来执行它们。

 public IEnumerable Where(Expression> selector) { // detect equality of the Id member and return some special value } 

考虑System.Linq.Enumerable.Reverse() – 此方法在返回第一个结果之前完全枚举IEnumerable。

如果您的查询是myCollection.Reverse()。Take(10),并且您的集合有数十亿项,那么枚举数十亿项以获得10项是一个可怕的想法。

如果您在自己的类型上提供了Reverse方法,则可以提供更好的实现,只需在集合上向后循环(可能通过索引)。

关键是提供您自己的类型来控制实现。 您不能使用适用于所有IEnumerable的实现,因为这些实现不会充分利用您的自定义集合类型的function。

是否可以使用可能的MoveNext,MovePrev等实现自己的IEnumerable,并拥有利用这些优势的已实现的LINQ扩展?

IEnumerable (或更恰当地说, IEnumerator )没有MovePrev 。 您可以定义一个接口:

 public interface IReversable : IEnumerable { IEnumerator GetReverseEnumerator(); } 

这可以由支持有效反向枚举的任何容器实现。

然后你可以编写Reverse的重载(扩展方法)来处理这个新接口,以及实现接口的集合类等等。然后你必须使用那些集合类而不是像List这样的标准类。 。

但是(我没有Reflector方便检查)可能是内置的Reverse足够智能,如果它可以从集合中获取IList接口,那么可以快速地做事情,这将优化最常见的情况就好了无论如何。

因此,这种方法可能没有太多意义。