在我正在开发的项目中,实际上有大量的集合(1M-1B元素),并且事物主要被修改为集合。
这是一款实时应用,因此性能至关重要。
对于某些操作,如Reverse,BinarySearch(可能的?)等会比Select等等遭受更多的打击。
使用可能的MoveNext,MovePrev等实现自己的IEnumerable是否可行,并且自己实现了利用这些扩展的LINQ扩展?
如果发生这种情况,它将在项目结束时发生。因为我们需要先让它工作,然后加快速度。
总而言之,这不应该是太多的工作,对吗?
答案 0 :(得分:9)
非常有可能创建自己的Enumerable
实现,这可能是特殊情况下的某些情况。您基本上想要检测自己的集合类型(或者可能只是集合,例如List<T>
),并在适用的情况下使用更有效的实现。
我有一个sample project,我曾用它来演示“在一小时内实现LINQ to Objects”,您可能需要查看这些示例。它不是一个完整的实现,特别是它比实际的LINQ to Objects 更少效率 - 但你仍然可能觉得它很有趣。
或者,您可能会发现i4o (Indexed LINQ)完成了您需要的所有内容 - 或者您最好不要从头开始做出贡献。值得一试。
请记住,在一天结束时,LINQ基本上是一个很好的设计加上语法糖。例如,C#编译器不知道关于System.Linq.Enumerable
的任何特殊内容。
答案 1 :(得分:2)
如果你真的想要表现,你可以做很多事情。请记住以下选择:
var result = from element in collection
where element.Id == id
select element;
编译为:
var result = collection.Where(element => element.Id == id);
如果为collection
类型创建以下方法,则可以利用主要操作与Id成员相等的事实,并以优化的方式处理请求。重要的是正确识别集合中的性能关键操作,并选择正确的算法(即复杂性)来执行它们。
public IEnumerable<TElement> Where(Expression<Func<TElement, bool>> selector)
{
// detect equality of the Id member and return some special value
}
答案 2 :(得分:2)
考虑System.Linq.Enumerable.Reverse() - 此方法在返回第一个结果之前完全枚举IEnumerable。
如果您的查询是myCollection.Reverse()。Take(10),并且您的集合中有数十亿项,那么枚举数十亿项以获得10项是一个可怕的想法。
如果你在自己的类型上提供了一个Reverse方法,你可以提供一个更好的实现,它只是在集合上向后循环(可能是索引)。
关键是提供您自己的类型来控制实现。您不能使用适用于所有IEnumerable<T>
的实现,因为这些实现不会充分利用您的自定义集合类型的功能。
答案 3 :(得分:1)
实施自己的可行性是否可行 IEnumerable与可能的MoveNext, MovePrev等自己实现了LINQ 利用的扩展 这些?
IEnumerable
(或更恰当地,IEnumerator
)没有MovePrev
。您可以定义一个界面:
public interface IReversable<T> : IEnumerable<T>
{
IEnumerator<T> GetReverseEnumerator();
}
这可以由支持有效反向枚举的任何容器实现。
然后你可以写一个Reverse
的重载(扩展方法)来处理这个新接口,以及实现接口的集合类等等。然后你必须使用那些集合类而不是标准的,如List<T>
。
但是(我没有方便检查反射器)可能内置的Reverse
足够智能,如果可以从IList
接口获得{{1}}接口,则可以快速做事。收集,无论如何都会优化最常见的情况。
因此,这种方法可能没有太多意义。