简体   繁体   English

改善LINQ查询性能

[英]Improve LINQ query performance

Assuming there is a class 假设有一堂课

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; }
}

I have to read data from a CSV file and map it to the mentioned class. 我必须从CSV文件中读取数据并将其映射到所提到的类。 The CSV file can have many records, in my case about 500000 records. CSV文件可以包含许多记录,在我的情况下为约500000条记录。

After I parse CSV file and map data to list of StopTime in different functions I want to filter StopTimes based on TripId . 在我解析CSV文件并将数据映射到具有不同功能的StopTime列表之后,我想根据TripId过滤StopTimes In my scenario I've about 8000 TripId s in the list of StopTime . 在我的场景中,我在StopTime列表中大约有8000个TripId

I have tried to create a Dictionary of a list using this code: 我试图使用以下代码创建列表的字典:

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

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

To create the dictionary, this loop has to filter StopTime s, remember 500000 records and 8000 instances of TripIds. 要创建字典,此循环必须过滤StopTime ,记住500000条记录和8000个TripId实例。

However, this is a very time consuming task. 但是,这是非常耗时的任务。 Is there a way to improve the performance? 有没有办法提高性能?

It sounds like you want a lookup : 听起来您想要查找

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

Or to narrow it down by ListOfTripId first: ListOfTripId缩小范围:

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

In both cases you'll only need to iterate through StopTimes once. 在这两种情况下,您只需要遍历StopTimes一次即可。

You can create a lookup table instead. 您可以改为创建查找表。

Represents a collection of keys each mapped to one or more values. 表示键的集合,每个键都映射到一个或多个值。

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

I've suggested loop changing: go through StopTimes , something like this: 我建议循环更改:经过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 });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM