【发布时间】:2014-03-30 11:30:52
【问题描述】:
我有一个全年 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 循环?
【问题讨论】:
-
你真的需要临时的
List<DataPoint>实例吗? -
它有很大的不同吗?这是简化逻辑,我将此列表传递给其他方法。但问题是 data.Where(x => x.TimeStamp >= from && x.TimeStamp
-
@kosnkov 这很重要,您在每个循环中都创建了一个数组。不仅你循环序列两次(一个是
ToList另一个是Sum) -
可能会进行进一步优化,但我会开始尝试省略该临时列表。是的,它可以有所作为;当您不需要任何列表时,您正在分配
List<DataPoint>并添加data的子集。如果您只想将选择命令分成几行,请将valuesToAgregate声明为IEnumerable<DataPoint>并省略ToList()调用 - 您将获得相同的简化(在可读性方面),但不会保存子集介于两者之间;它将被懒惰地评估。 -
您可以优化的另一个细节是,目前,您为每个项目调用
from.AddHours(1)(在传递给Where的 lambda 表达式中,而不是将结果存储在变量中,然后在 lambda表达式。编译器可能不会自行优化它,因为它不知道对from.AddHours(1)的每次调用是否为给定的from返回相同的值。
标签: c#