在复杂的图像处理算法的最后,我们有以下代码将结果保存到文本文件。该函数的输入是一个float[,] p_RangeMap
表示图像处理的输出:.net性能周期?
StringBuilder stringBuilder = new StringBuilder(30 * 1024 * 1024);
stringBuilder.AppendLine("Row" + ms_csvSeparator + p_RangeMap.GetLength(0));
stringBuilder.AppendLine("Col" + ms_csvSeparator + p_RangeMap.GetLength(1));
Stopwatch stopwatch = Stopwatch.StartNew();
for (int y = 0; y < p_RangeMap.GetLength(0); y++)
{
for (int x = 0; x < p_RangeMap.GetLength(1); x++)
{
stringBuilder.Append(p_RangeMap[y, x].ToString(CultureInfo.InvariantCulture));
stringBuilder.Append(ms_csvSeparator);
}
stringBuilder.AppendLine();
}
stopwatch.Stop();
Console.WriteLine("MeasureRunTime: RangemapConvert: " + stopwatch.Elapsed);
通过测量这些线6000次的迭代的运行时,我们得到了如下图:
6000迭代大约需要24小时才能运行。水平轴表示迭代,垂直轴表示这些线以秒计算的运行时间。输入对于每次迭代完全相同,并且p_RangeMap的尺寸是1312 x 3500.
它从大约两秒开始,并且在上升到13秒之后,在900次迭代之后回落,并且(大约)900个周期形成一个周期。正如你所看到的最高值约为22秒。
任何想法可能导致这种运行时变化?
什么可能导致周期性?
可能值得一提的是,代码的其他部分显示了相同的行为,但是这部分是从源代码中最容易获取的。
UPDATE1:
我已经更新了代码示例中,StringBuilder的是预分配与文件大小的一个粗略的估计。我们也考虑过垃圾回收,请考虑以下事项:
900个周期意味着大约3.5小时,大约16 GB的处理后的输入数据(从文件一次又一次地加载相同的图片)。更不用说因为各种原因在图像处理过程中创建的副本。我认为GC应该更频繁地触发。
16 GB来源于:1312 * 3500 * 4 * 900
考虑到操作涉及分配,我希望垃圾收集... –
考虑预先分配的StringBuilder - 我认为结果是相当大的,如果它有它的效率不高经常扩大规模。如果结果进入一个文件,请考虑在一个较小的stringbuilder中逐行输出它 - 这看起来像gc问题,这是一个可能的原因。 – TomTom
我已经更新了这个问题,StringBuilder是预先分配的。逐行输出这些线条听起来很有意思,我们可以尝试。将更新与结果的职位。 – toderik