假设我们有一个排序集合,例如带有许多 (10M+) 元素的SortedSet或SortedList 。正在发生大量查询,因此性能很重要。从运行时比较来看,我的印象是 LINQ to Objects 没有利用排序,因此没有利用潜在的性能提升。
第一个示例 - 计算范围内的元素:
var mySortedSet1 = new SortedSet<int>();
// populate ...
int rangeCount = (from n in mySortedSet1
where ((n >= 1000000000) && (n <= 2000000000))
select n).Count();
不完全确定 LINQ to Objects 在内部做了什么,最坏的情况是检查每一个 O(n) 的元素。通过利用对 O(log n) 中的下限和上限进行二分搜索的排序,可以更快地完成。
第二个示例 - SelectMany 在集合列表中:
var myListOfSortedSets = new List<SortedSet<int>>();
// populate...
var q = myListOfSortedSets.SelectMany(s => s).OrderBy(s => s);
foreach (var n in q)
{
Console.WriteLine(n);
}
如果 LINQ to SQL对象要利用排序,它可以在 O(n) 中有效地将所有排序集压缩合并到一个大的排序列表中。结果上的 .OrderBy 然后可以被忽略,因为列表已经排序。
相反,SelectMany 将所有已排序的集合连接到一个大的(现在未排序的)列表中,这将需要另一个 O(n log n) 排序。这可以通过删除 .OrderBy 并观察元素写入控制台的顺序来轻松验证。
我的问题是:是否已经有另一种更有效的 LINQ to SortedSet/SortedList 实现?
i4o看起来很有趣,但似乎需要二级索引集合来提高对原始集合的查询性能。我只是希望通过利用排序来更快地对排序集合进行查询。