汇总数据结果的最佳方式

时间:2014-05-20 17:59:27

标签: c# performance linq

我有一个应用程序执行一些代码A多次迭代,通常最多1M次迭代。 在代码A执行完之后,我收集信息,如时间,错误消息,如果抛出异常等,在专门的对象中让我们说ExecutionInfo。然后我在ConcurrentBag中添加了ExecutionInfo的实例(没关系ConcurrentBag,它可能也是一个List但需要是线程安全的)。

在1M次迭代后,我得到了一组1M ExecutionInfo实例。下一步是将所有内容汇总为ExecutionInfoAggregation,使用Linq扩展,例如Average,Min,Max,Count来获取各种有趣的数据。以下代码在1M次迭代后运行,并消耗92%的CPU(表示探查器):

    private void Summarize(IEnumerable<MethodExecutionResult> methodExecutions)
    {
        List<MethodExecutionResult> items = methodExecutions.ToList();
        if (!items.Any())
        {
            return;
        }  
        AvgMethodExecutionTime = Math.Round(items.Average(x => x.ExecutionTime.TotalMilliseconds),3);
        MinMethodExecutionTime = Math.Round(items.Min(x => x.ExecutionTime.TotalMilliseconds),3);
        MaxMethodExecutionTime = Math.Round(items.Max(x => x.ExecutionTime.TotalMilliseconds),3);

        FailedExecutionsCount = items.Count(x => !x.Success);

    }

顺便说一下,应用程序的内存使用量是“暴涨”#。

这显然不具备高效性。我对此的解决方案如下:

使用更合适的集合类型替换集合类型,允许快速插入和快速查询。那可能是什么,如果有的话? 不要在1M迭代后查询集合,而是在每次执行代码后聚合。 尝试找到一种更紧凑的方式来存储收集的数据。

如何优化查询的任何想法?有更好的方法吗?

编辑:刚看到没有必要调用ToList()

1 个答案:

答案 0 :(得分:0)

我会在每次执行方法后聚合它们,而不是保存每次执行的信息。

public class MethodExecutions
{
    private int _excCount = 0;
    private Int64 _totalExcTime = 0;
    private int _excMaxTimeTotalMilliseconds = 0;
    private int _excMinTimeTotalMilliseconds = int.MaxValue;
    private int _failCount = 0;

    public void Add(int excTime, bool isFail)
    {
        _excCount += 1;
        _totalExcTime += excTime;

        if (excTime > _excMaxTimeTotalMilliseconds)
            _excMaxTimeTotalMilliseconds = excTime;

        if (excTime < _excMinTimeTotalMilliseconds)
            _excMinTimeTotalMilliseconds = excTime;

        if (isFail)
            _failCount++;
    }

    public void Summarize(out int avgTime, out int minTime, out int maxTime, out int failCount)
    {
        avgTime = (int) Math.Round((double) _totalExcTime / _excCount);
        minTime = _excMinTimeTotalMilliseconds;
        maxTime = _excMaxTimeTotalMilliseconds;
        failCount = _failCount;
    }
}