提高LINQ查询性能

时间:2013-12-17 08:07:44

标签: c# linq dictionary

假设有一个班级

public class StopTime
{
    public TimeSpan? ArrivalTime { get; set; }
    public TimeSpan? DepartureTime { get; set; }
    public string StopID { get; set; }
    public int StopSequence { get; set; }
    public string TripID { get; set; }
}

我必须从CSV文件中读取数据并将其映射到上述类。 CSV文件可以有很多记录,在我的情况下大约有500000条记录。

在我解析CSV文件并将数据映射到不同功能的StopTime列表后,我想根据StopTimes过滤TripId。 在我的方案中,我在TripId列表中大约有8000 StopTime个。

我尝试使用以下代码创建列表字典:

var TripIdStops = new Dictionary<string, List<StopTime>>();

foreach (var tripId in ListOfTripId)
{
    TripIdStops.Add(tripId, StopTimes.Where(x=>x.TripID==tripsDistinct).ToList());
}

要创建字典,此循环必须过滤StopTime,记住500000条记录和8000条TripIds实例。

然而,这是一项非常耗时的任务。有没有办法改善表现?

3 个答案:

答案 0 :(得分:2)

听起来你想要一个lookup

var stopTimesByTripId = StopTimes.ToLookup(st => st.TripId);

或者先将ListOfTripId缩小范围:

var tripIdSet = new HashSet<string>(ListOfTripId);
var stopTimesByTripId = StopTimes.Where(st => tripIdSet.Contains(st.TripId))
                                 .ToLookup(st => st.TripId);

在这两种情况下,您只需要迭代StopTimes一次。

答案 1 :(得分:1)

您可以改为创建lookup表。

  

表示每个映射到一个或多个值的键集合。

var lookup = StopTimes.ToLookup(st => st.TripId);

答案 2 :(得分:1)

我建议循环更改:浏览StopTimes,等等 像这样:

var TripIdStops = new Dictionary<string, List<StopTime>>();

foreach (var time in StopTimes) {
  List<StopTime> list;

  if (TripIdStops.TryGetValue(time.TripID, out list))
    list.Add(time);
  else
    TripIdStops.Add(time.TripID, new List<StopTime>() { time });
}