【发布时间】:2021-11-04 00:52:57
【问题描述】:
我有以下算法适用于较小的日期范围,但是如果我将日期范围增加到大约一年(startDate,endDate),它显然会降低性能,因为我每天每一分钟都在循环,是有没有办法通过使用不同的列表类型(例如哈希集或字典)来提高性能,或者还有其他我不知道的后备方法吗?
listWorkTime 包含大约 300 多个条目,其中某些日期范围可能重叠或相同但具有不同的 TimeRangeId
private List<DateSharedWork> CalculateDateSharedWork(DateTime startDate,
DateTime endDate, ICollection<WorkTime> listWorkTime)
{
List<DateSharedWork> listDateSharedWork = new List<DateSharedWork>();
// +1 to include last day at full
int range = endDate.Subtract(startDate).Days + 1;
// start at startDate
Parallel.For(0, range, i =>
{
DateTime currDate = startDate.AddDays(i);
//set minute interval
double everyNMinutes = 1.0;
double minutesADay = 1440.0;
// reset counter
int work_counter = 0;
int lowWork_counter = 0;
int noWork_counter = 0;
int l = (int)(minutesADay / everyNMinutes);
for (int j = 0; j < l; j++)
{
DateTime check15 = currDate.AddMinutes(j * everyNMinutes);
// check if listWorkTime includes current date
var foundTime = listWorkTime
.Where(x => check15 >= x.FromDate && check15 <= x.ToDate).ToList();
if (foundTime.Count(x => x.TimeRangeId == 1) > 0)
{
// found interval that is within work hours
work_counter++;
noWork_counter++;
}
else
{
if (foundTime.Count(x => x.TimeRangeId == 2) > 0)
{
// found intervall that is within low work hours
lowWork_counter++;
noWork_counter++;
}
}
};
double work = everyNMinutes / minutesADay * work_counter;
double lowWork = everyNMinutes / minutesADay * lowWork_counter;
double noWork = 1.0 - (everyNMinutes / minutesADay * noWork_counter);
listDateSharedWork.Add(new DateSharedWork(currDate, work, lowWork, noWork));
});
listDateSharedWork.Sort((x, y) => DateTime.Compare(x.Date, y.Date));
return listDateSharedWork;
}
编辑*
类定义
public class DateSharedWork
{
public DateSharedWork(DateTime date, double? work = 0.0, double? lowWork = 0.0, double? noWork = 1.0)
{
this.Date = date;
this.Work = work.Value;
this.LowWork = lowWork.Value;
this.NoWork = noWork.Value;
}
public DateTime Date { get; private set; }
public double Work { get; private set; }
public double LowWork { get; private set; }
public double NoWork { get; private set; }
}
【问题讨论】:
-
能否请您也发布您的
DateSharedWork类型? -
附带说明请注意
List<T>类不是线程安全的。从多个线程并行调用listDateSharedWork.Add方法可能会导致内部状态损坏。 -
首先使用
Where()过滤输入列表,然后您是否尝试使用GroupBy()对输入进行分组,如@987654332 @?完成后,您已经知道输出列表中的项目数(预分配)并简单地遍历每个存储桶。另请注意,您不能对minutesADay之类的内容进行硬编码(时间变化...)
标签: c# list performance loops dictionary