聚合值需要很长时间

时间:2014-03-30 11:30:52

标签: c#

我有一个大的15分钟值列表。我想将它们合并为几个小时。我是以非常简单的方式做到的:

for (; from <= to; from = from.AddHours(1))
{
    List<DataPoint> valuesToAgregate = data.Where(x => x.TimeStamp >= from && x.TimeStamp < from.AddHours(1)).ToList();
    dailyInputData.Add(valuesToAgregate.Sum(x=>x.Val));

}

这种方式需要花费很多时间,例如35k值的30秒,是否有任何方法可以优化它?也许使用排序功能或一些如何添加索引列表或使用分组而不是for循环?

2 个答案:

答案 0 :(得分:2)

当然,如果您之前通过TimeStamp订购列表,这将更快。例如:

var orderedData = data.OrderBy(item => item.TimeStamp).ToList();
int firstIndex = 0;
var from = orderedData.First().TimeStamp;
var to = orderedData.Last().TimeStamp;
while (from < to)
{
    var sum = 0;
    var newTo = from.AddHours(1);
    while (firstIndex < data.Count && orderedData[firstIndex].TimeStamp < newTo)
    {
        sum += orderedData[firstIndex].Val;
        ++firstIndex;
    }
    dailyInputData.Add(sum);
    from = from.AddHours(1);
 }

答案 1 :(得分:1)

data = data.Sort(x=>x.TimeStamp);
int counter = 0;
var boundary = from.AddHours(1);
foreach(var d in data){
    if(d.TimeStamp > boundary){
        boundary = boundary.AddHours(1);
        counter = 0;
        dailyInputData.Add(counter);
    }
    ++counter;
}

这个问题在于逻辑

  1. 每次从头到尾扫描列表以查找候选值(您的where子句)
  2. 将候选值插入另一个临时列表
  3. 然后从开始到结束扫描临时列表以计算总和
  4. 最快的方法:

    1. 对列表进行排序
    2. 浏览项目,如果它们属于当前组,则添加计数器,否则您已跳转到新组,刷新计数器以记录该值并重新开始