C# 提高时间间隔计算的性能
我有下面的代码片段,第一个是短版本,第二个是竞争版本,然后循环遍历大量按时间顺序排列的记录。记录的数量从十万到几百万不等。我需要比较连续记录之间的时间间隔,并确定以分钟为单位的差异,以决定某些操作并设置值。这是整个应用程序的性能瓶颈,所以我需要做点什么。剖析器清楚地表明C# 提高时间间隔计算的性能,c#,performance,datetime,C#,Performance,Datetime,我有下面的代码片段,第一个是短版本,第二个是竞争版本,然后循环遍历大量按时间顺序排列的记录。记录的数量从十万到几百万不等。我需要比较连续记录之间的时间间隔,并确定以分钟为单位的差异,以决定某些操作并设置值。这是整个应用程序的性能瓶颈,所以我需要做点什么。剖析器清楚地表明 (DayList[nextIndex].ThisDate - entry.ThisDate).Minutes 瓶颈是瓶颈中的瓶颈。解决此问题后,下一个瓶颈将是DayList创建中的日期调用: List<Monthfile
(DayList[nextIndex].ThisDate - entry.ThisDate).Minutes
瓶颈是瓶颈中的瓶颈。解决此问题后,下一个瓶颈将是DayList创建中的日期调用:
List<MonthfileValue> DayList = thisList.Where(x => x.ThisDate.Date == i.Date).ToList();
这两条线大约占所有CPU的60%-70%
因此,问题是:我如何才能大幅提高性能,还是应该完全放弃这条路,因为这种性能是不可接受的
for ( DateTime i=startdate; i<=enddate; i=i.AddDays(1) )
{
int nextIndex = 0;
List<MonthfileValue> DayList = thisList.Where(x => x.ThisDate.Date == i.Date).ToList();
foreach (MonthfileValue entry in DayList)
{
if (++nextIndex < DayList.Count - 1)
{
IntervalInMinutes = (DayList[nextIndex].ThisDate - entry.ThisDate).Minutes;
}
// do some calculations
}
// do some calculations
}
完整版本如下:
for ( DateTime i=startdate; i<=enddate; i=i.AddDays(1) )
{
int nextIndex = 0;
DaySolarValues tmp = new DaySolarValues();
List<MonthfileValue> DayList = thisList.Where(x => x.ThisDate.Date == i.Date).ToList();
foreach (MonthfileValue entry in DayList)
{
if (++nextIndex < DayList.Count - 1)
{
OldIntervalInMinutes = IntervalInMinutes;
IntervalInMinutes = (DayList[nextIndex].ThisDate - entry.ThisDate).Minutes;
if (IntervalInMinutes > 30)
{
IntervalInMinutes = OldIntervalInMinutes; //reset the value and try again
continue; // If more than 30 minutes, then skip this data
}
else if (IntervalInMinutes != OldIntervalInMinutes)
{
// Log some message and continue
}
}
tmp.SolarHours += entry.SolarRad / entry.SolarTheoreticalMax >= SunThreshold ? IntervalInMinutes : 0;
tmp.SolarEnergy += entry.SolarRad * IntervalInMinutes * 60;
tmp.SunUpTimeInMinutes += IntervalInMinutes;
}
tmp.SolarHours /= 60;
tmp.SolarEnergy /= 3600;
tmp.ThisDate = i;
DailySolarValuesList.Add(tmp);
}
我可以清楚地看到,在哪里。。。电话窃取性能。 对我来说,这将是尝试这一点的第一步:
var dayLookup = thisList.ToLookup(x => x.ThisDate.Date);
for ( DateTime currentDate =startdate; currentDate <=enddate; currentDate = currentDate.AddDays(1) )
{
int nextIndex = 0;
List<MonthfileValue> DayList = dayLookup[currentDate];
...
}
通过这种方式,您可以在循环之前创建一个哈希查找,因此获取DayList将是一个成本较低的操作只需使用适当的数据结构哈希映射即可?DayList是为for DateTime i=startdate的每个循环创建的;您的问题中有很多代码似乎与时间跨度计算性能问题无关。您能否通过删除所有不相关的噪声并保留再现问题的绝对最小值来简化代码?在我看来,行DayList[nextIndex].ThisDate-entry.ThisDate.Minutes中的代码本身不应该太慢。我认为计算应该很快。问题可能是它运行了很多次。如果可能的话,你应该尝试修正你的算法,这样这一行就不会运行那么多次。如果你用简单的术语描述你的程序应该做什么,那么修复你的算法就容易多了。顺便说一句,有一个可变的日期时间我真的很困惑。比如有一个变量int date或string number。这个命名方案可能对工作安全性很好,但对其他任何目的都不太好。我可以补充一点,时差没有那么大的影响。瓶颈在其他地方,但要小得多。所以我的问题基本上解决了。谢谢。有些用户可能会对他们第一次快速阅读时无法理解的问题非常挑剔,并希望海报尽可能减少他们的问题。就我个人而言,我理解,当你陷入一个问题时,创造一个完美的问题并不总是那么容易。@HansRottier你发布的分析信息不是大错特错吗?如果第一个瓶颈和第二个瓶颈的总和是60-70%,那么解决第二个瓶颈怎么能使其速度提高75%?@HansRottier关于否决票-另一个可能的原因可能是您只是发布了一段不完整的代码片段,留下了几个未定义的变量。通常,您可以为这个列表、startdate和enddate生成随机值。看。@HansRottier他们并不矛盾这种假设是危险的,尽管在这种特殊情况下是正确的。应始终张贴可复制的示例。