gpt4 book ai didi

c# - 取消嵌套列表迭代以提高性能

转载 作者:太空宇宙 更新时间:2023-11-03 20:31:00 25 4
gpt4 key购买 nike

为了执行计算,我需要遍历多个列表。总之,List1 是道路起点和终点 (ids) 的列表,List2 是这些终点的单个速度样本的列表(每组终点都有多个速度样本)。 List1 定义如下:

class RoadwaySegment
{
public int StartId {get; set;}
public int EndId {get; set;}
}

List2 定义如下:

class IndividualSpeeds
{
public int StartHour {get; set;}
public int StartMin {get; set;} //either 0,15,30,or 45
public int Speed {get; set;}
public int StartId {get; set;}
public int EndId {get; set;}
}

List3 是我的计算结果,将包含 List1 中道路路段在一天中每 15 分钟的平均速度。 List3 看起来像这样:

class SummaryData
{
public string SummaryHour {get; set;}
public string SummaryMin {get; set;}
public int StartId {get; set;}
public int EndId {get; set;}
public int AvgSpeed {get; set;}
}

目前,为了生成 List3,我对 List1 进行迭代,然后在一天中的每 24 小时内迭代,然后在每小时的每 15 分钟间隔内迭代。对于这些迭代中的每一个,我检查 List2 中的单个速度样本是否应该包含在我的道路段的平均速度计算中。所以,它看起来像这样:

var summaryList = new List<SummaryData>();
foreach (var segment in RoadwaySegments)
{
for(int startHour = 0; startHour < 24; startHour++)
{
for(int startMin = 0; startMin < 60; startMin+= 15)
{
int totalSpeeds = 0;
int numSamples = 0;
int avgSpeed = 0;

foreach(var speedSample in IndividualSpeeds)
{
if((segment.StartId == speedSample.StartId)&&(segment.EndId == speedSample.EndId)&&(speedSample.StartHour == startHour)&&(speedSample.StartMin == startMin))
{
if(speedSample.Speed > 0)
{
totalSpeeds += speedSample.Speed;
numSamples += 1;
}
}
}
SummaryData summaryItem = new SummaryData {SummaryHour = startHour, SummaryMin = startMin, StartId = segment.StartId, EndId = segment.EndId, AvgSpeed = totalSpeeds/numSamples;
summaryList.Add(summaryItem);
}
}
}

此代码的问题在于,List1 可能有一百个路段,但 List2 可能包含一百万或更多速度样本记录,因此列表的子迭代非常耗时。有没有办法使用 GroupBy/LINQ 来提高这段代码的性能和可读性?请注意在平均值中包括速度的条件——它必须大于 0。

最佳答案

这是未经测试的,但我认为它会起作用:

from segment in RoadwaySegments
join sample in IndividualSpeeds on new { segment.StartId, segment.EndId } equals new { sample.StartId, sample.EndId } into segmentSamples
from startHour in Enumerable.Range(0, 24)
from startMin in new[] { 0, 15, 30, 45 }
let startMinSamples = segmentSamples
.Where(sample => sample.Speed > 0)
.Where(sample => sample.StartHour == startHour)
.Where(sample => sample.StartMin == startMin)
.Select(sample => sample.Speed)
.ToList()
select new SummaryItem
{
StartId = segment.StartId,
EndId = segment.EndId,
SummaryHour = startHour,
SummaryMin = minute,
AvgSpeed = startMinSamples.Count <= 2 ? 0 : startMinSamples.Average()
};

主要思想是迭代片段和样本列表一次,为每个片段生成一组样本。然后,对于这些组中的每一个,您为每个组合生成小时和分钟以及摘要项。最后,您计算小时/分钟组合中所有非零样本的平均速度。

这不是很理想,因为您仍然将片段的样本迭代 24 * 4 次,但它比迭代整个样本列表要好得多。这应该会让您走上正确的道路,希望您可以进一步优化最后一点。

关于c# - 取消嵌套列表迭代以提高性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7573884/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com