.net 分类集<;T>;包含vs Linq查询

.net 分类集<;T>;包含vs Linq查询,.net,linq-to-objects,.net,Linq To Objects,我有一个非常简单的SortedSet,它带有一个CompareTo方法,该方法基于两个类字段进行排序。在使用时,此集合可以获得相当大的对象(超过百万个),并随着时间的推移不断增长。我一直在使用一个简单的Contains方法来确定集合中是否已经存在一个新值 作为一项学术练习,我正在使用Linq进行一些基准测试(我对Linq还比较陌生)为了达到同样的效果,我确信我对Linq缺乏一些理解,因为我无法接近同样的性能,我想知道是否有Linq大师可以给我一个指针,告诉我可以做些什么来加速它 所以。。。该对象

我有一个非常简单的SortedSet,它带有一个CompareTo方法,该方法基于两个类字段进行排序。在使用时,此集合可以获得相当大的对象(超过百万个),并随着时间的推移不断增长。我一直在使用一个简单的Contains方法来确定集合中是否已经存在一个新值

作为一项学术练习,我正在使用Linq进行一些基准测试(我对Linq还比较陌生)为了达到同样的效果,我确信我对Linq缺乏一些理解,因为我无法接近同样的性能,我想知道是否有Linq大师可以给我一个指针,告诉我可以做些什么来加速它

所以。。。该对象有一个类似于以下内容的CompareTo:

public int CompareTo(EntityHistoryChange other)
{
    int recordIdComp = Recordid.CompareTo(other.Recordid);
    int tableIdComp = Tablename.CompareTo(other.Tablename);

    if (recordIdComp == 0 && tableIdComp == 0)
        return 0;
    else if (recordIdComp != 0)
        return recordIdComp;
    else
        return tableIdComp;
}
简单列表上对应的Linq查询:

var handledChange = from thisChange in handledChanges
                    where thisChange.Recordid == recordId 
                      && thisChange.Tablename == tableName
                    select thisChange;
我想结果应该不会让我惊讶

Linq Lookup on 18772 rows: 46 ms
SortSet Lookup on 18772 rows: 3 ms

所以问题是-什么是等效的LINQ机制

许多LINQ操作符检查IEnumerable之外的接口并利用它们


例如,
Count
将检查
ICollection
并使用其Count属性,而不是遍历整个集合。查看这些(基准之外)的唯一方法是查看IL(或使用Refector),当然,新的.NET版本(包括SP)可能会改变实现。例如,在.NET r.5中,
Count
没有检查
ICollection
,但它在4中检查。

Linq将永远不会像这样快,因为Linq看到的对象不是SortedSet,而是
IEnumerable
,它除了“给我一个对象列表”之外没有其他语义。你根本没有利用场景的优势


SortedSet
排序依据是什么?这不就是通过SortedSet.Contains进行的查找吗?然后您可以检查表名?

LINQ并不是为了取代对给定作业使用正确的数据结构。它只是使处理这些数据结构变得更容易。如果您将数据存储在SQL数据库中,您仍然需要在DB上使用智能索引来提高性能。同样,使用LINQ to对象,您需要在适当的情况下利用数据结构,如
SortedSet

因此,您的问题的答案是:模拟Contains方法的LINQ查询将是:

var exists = handledChanges.Any(c => c.Recordid = recordId && c.Tablename == tableName);
但是,如果您使用LINQ to对象,这将永远无法实现与在数据结构上使用Contains方法相同的性能,该数据结构是专门为快速查找而定制的。如果您使用LINQtoSQL或LINQtoEntities,这将提供一个优化的SQL查询,它可以运行得非常快


顺便说一下,如果您的目标是在内存中收集更快的查找,您可能需要考虑使用自定义的IEQualy比较器使用哈希集。它的Contains方法在数百万个对象的集合上所用的时间应该与在10个对象的集合上所用的时间一样长。

考虑到Linq添加的抽象层,这看起来性能相当好。