0

我正在搜索包含 3 列的通用列表(或 IQueryable)。我正在尝试根据 1 和 2 查找第 3 列的值,但搜索速度确实很慢。对于单个搜索,速度并不明显,但我正在循环执行此搜索,并且对于 700 次迭代,总共需要 2 多分钟的时间,这没有任何用处。第 1 列和第 2int列是,第 3 列是 a double。这是我正在使用的 linq:

public static Distance FindByStartAndEnd(int start, int end, IQueryable<Distance> distanceList)
{
    Distance item = distanceList.Where(h => h.Start == start && h.End == end).FirstOrDefault();
    return item ;
}

IQueryable 列表中最多可能有 60,000 个条目。我知道这很多,但我认为这不会对搜索造成任何问题。

所以我的问题是,当需要匹配两列以获得第三列的值时,是否有更好的方法来搜索集合?我想我需要所有 700 次搜索几乎是即时的,但每个搜索都需要大约 300 毫秒,很快就会增加。

更新 - 最终解决方案#######################

我现在使用Tuplewithstartend作为键创建了一个字典。我认为这可能是正确的解决方案。

var dictionary = new Dictionary<Tuple<int, int>, double>();

var key = new Tuple<int, int>(Convert.ToInt32(reader[0]), Convert.ToInt32(reader[1]));
var value = Convert.ToDouble(reader[2]);

if (value <= distance)
{
    dictionary.Add(key, value);
}
var key = new Tuple<int, int>(5, 20);

工作正常 - 更快

4

5 回答 5

5

创建一个字典,其中第 1 列和第 2 列创建键。您创建字典一次,然后您的搜索将几乎是即时的。

于 2012-10-24T09:06:56.643 回答
0

如果您可以控制您的集合和模型类,那么有一个库可以让您索引类的属性,这可以大大加快搜索速度。

http://i4o.codeplex.com/

于 2012-10-24T09:07:25.223 回答
0

从前两列中创建一个值,例如通过将它们连接到 along中,并将其用作字典中的键:

public long Combine(int start, int end) {
  return ((long)start << 32) | end;
}

Dictionary<long, Distance> lookup = distanceList.ToDictionary(h => Combine(h.Start, h.End));

然后您可以查找该值:

public static Distance FindByStartAndEnd(int start, int end, IQueryable<Distance> distanceList) {
  Distance item;
  if (!lookup.TryGetValue(Combine(start, end), out item) {
    item = null;
  }
  return item;
}

从字典中获取项目接近于 O(1) 操作,这应该与 O(n) 操作产生显着差异,以循环遍历项目以找到一个。

于 2012-10-24T09:14:07.587 回答
0

您的问题是每次返回项目时 LINQ 都必须执行表达式树。只需使用多个开始和结束值调用此方法

public static IEnumerable<Distance> FindByStartAndEnd
    (IEnumerable<KeyValuePair<int, int>> startAndEnd,
    IQueryable<Distance> distanceList)
{

    return
        from item in distanceList
        where 
            startAndEnd.Select(s => s.Key).Contains(item.Start)
            && startAndEnd.Select(s => s.Value).Contains(item.End)
        select item;
}
于 2012-10-24T09:09:16.727 回答
0

我会试试hashSet。这应该加快速度;)

于 2012-10-24T09:11:09.527 回答