加速查找集合中的数据范围

时间:2009-11-14 21:42:57

标签: c# linq collections linq-to-objects

说我有一个班级

public class TimestampedTrackId
{
    private readonly int trackId;
    private readonly DateTime insertTime;
    public TimestampedTrackId(int trackId, DateTime insertTime)
    {
        this.trackId = trackId;
        this.insertTime = insertTime;
    }

    public int TrackId
    {
        get
        {
            return trackId;
        }
    }

    public DateTime InsertTime
    {
        get
        {
            return insertTime;
        }
    }
}

我有一个类型为List<TimestampedTrackId>的大型列表,需要从此列表中提取TimestampedTrackId个实例,其中属性InsertTime位于最小和最大DateTime之间。

List<TimestampedTrackId> tracks; //Count=largeNumber
... 
tracks.Where(t=>t.InsertTime>min&&t.InsertTime<max)

List<T>显然不是此任务的正确容器,因为它需要搜索每个项目以检查InsertTime是否位于最小值和最大值之间。

所以,我假设加速这段代码的一部分将涉及在更合适的集合中重新打包列表,但是哪个集合?

鉴于正确的集合(可能是键控的),我可以使用什么查询来利用最大查找速度?

提前致谢

2 个答案:

答案 0 :(得分:4)

一个好的解决方案可能是使用TreeMap,因为该结构非常适合于获取小于或大于给定键的特定范围的键。

.NET本身没有一个,但有一个很好的implementation of one here

答案 1 :(得分:3)

您是否可以按InsertTime对列表进行排序?如果是,则List<T>.BinarySearch是您的朋友 - 提供IComparer<TimestampedTrackId>,其中InsertTimeBinarySearch minmax进行比较。 (您需要创建TimestampedTrackId InsertTimeminmax的“虚拟”BinarySearch对象才能搜索它们。)

如果InsertTime返回负值,则应使用按位补码(使用〜运算符)找出要插入值的索引。另请注意,如果多个项目具有相同的min,则您需要从max索引向后工作,并从{{1}}索引转发,以确保获得全部范围。无论如何,它仍然比线性搜索更有效率。不可否认,它更加繁琐:)