C# 秒表 - 返回不一致的值
C# Stopwatch - Returning inconsistent values
可能有重复但我不知道如何解释我的问题。
我 运行 我使用 .NET 秒表实现(在不同情况下)的 Floyd Rivest 算法的性能计时。
为了更好地理解问题,这里是代码。
我正在一个接一个地执行以下 3 个方法:
analysis.FRStopwatch(analysis.getOrderedArray());
analysis.FRStopwatch(analysis.getDescendingOrderedArray());
analysis.FRStopwatch(analysis.getUnorderedArray());
FRStopwatch(int[]) 方法执行以下操作:
public double FRStopwatch(int[] array)
{
frs = new FloydRivestSelection(array);
double avg = 0;
Stopwatch s = new Stopwatch();
for (int i = 0; i < k.Length; i++)
{
Thread.Sleep(10);
s.Start();
frs.Select(k[i]);
s.Stop();
avg = avg + (double)s.Elapsed.TotalMilliseconds;
s.Reset();
Console.WriteLine(avg);
}
avg = avg / (double)k.Length;
return avg;
}
我得到的输出如下:
Original Output
正如你所看到的,有序数组的时间比其他数组大得多。
然后我把第一行显示的注释掉了:
analysis.FRStopwatch(analysis.getOrderedArray());
并按以下顺序只执行剩下的两个:
analysis.FRStopwatch(analysis.getDescendingOrderedArray());
analysis.FRStopwatch(analysis.getUnorderedArray());
我得到以下输出:
New Output
似乎第一种使用秒表的方法工作不正常(或者其他两种方法工作不正常?)。我该如何修复才能使结果一致?问题是否与我的计算机有关(CPU ticks 等)?
这些行有问题:
avg = avg + (double)s.Elapsed.TotalMilliseconds;
Console.WriteLine(avg);
你增加了平均值,但你输出了总和。试试这个来输出 "current" 平均值。
avg = avg + (double)s.Elapsed.TotalMilliseconds;
Console.WriteLine(avg / (i+1));
或者,如果您对每次迭代的运行时间感兴趣:
Console.WriteLine(s.Elapsed.TotalMilliseconds);
//reset after instead of before of course
s.Reset();
您打印到控制台的是累计次数,不是平均次数,也不是个别次数。
我建议你像这样打印个人时间:
s.Start();
frs.Select(k[i]);
s.Stop();
var elapsed = (double)s.Elapsed.TotalMilliseconds;
avg = avg + elapsed; //it is really sum, not avg
s.Reset();
Console.WriteLine(elapsed);
我猜第一种方法的第一次迭代会消耗最多的时间,可能是因为JIT compilation。如果你打印个别时间,你会清楚地看到这一点。
另外,我建议你把变量名从avg
改成sum
,只计算循环后的平均值
一个小请求的单个样本受制于太多变数。
为了更好地了解性能,运行 每次执行几千次(比如 6000 次),然后丢弃前 1000 次左右的结果以消除任何预热因素(JIT/缓存等)。
将您的结果除以 5000 得到平均执行时间。这种方法将帮助您保持理智并更好地指示性能。
可能有重复但我不知道如何解释我的问题。
我 运行 我使用 .NET 秒表实现(在不同情况下)的 Floyd Rivest 算法的性能计时。
为了更好地理解问题,这里是代码。
我正在一个接一个地执行以下 3 个方法:
analysis.FRStopwatch(analysis.getOrderedArray()); analysis.FRStopwatch(analysis.getDescendingOrderedArray()); analysis.FRStopwatch(analysis.getUnorderedArray());
FRStopwatch(int[]) 方法执行以下操作:
public double FRStopwatch(int[] array)
{
frs = new FloydRivestSelection(array);
double avg = 0;
Stopwatch s = new Stopwatch();
for (int i = 0; i < k.Length; i++)
{
Thread.Sleep(10);
s.Start();
frs.Select(k[i]);
s.Stop();
avg = avg + (double)s.Elapsed.TotalMilliseconds;
s.Reset();
Console.WriteLine(avg);
}
avg = avg / (double)k.Length;
return avg;
}
我得到的输出如下: Original Output
正如你所看到的,有序数组的时间比其他数组大得多。
然后我把第一行显示的注释掉了:
analysis.FRStopwatch(analysis.getOrderedArray());
并按以下顺序只执行剩下的两个:
analysis.FRStopwatch(analysis.getDescendingOrderedArray()); analysis.FRStopwatch(analysis.getUnorderedArray());
我得到以下输出: New Output 似乎第一种使用秒表的方法工作不正常(或者其他两种方法工作不正常?)。我该如何修复才能使结果一致?问题是否与我的计算机有关(CPU ticks 等)?
这些行有问题:
avg = avg + (double)s.Elapsed.TotalMilliseconds;
Console.WriteLine(avg);
你增加了平均值,但你输出了总和。试试这个来输出 "current" 平均值。
avg = avg + (double)s.Elapsed.TotalMilliseconds;
Console.WriteLine(avg / (i+1));
或者,如果您对每次迭代的运行时间感兴趣:
Console.WriteLine(s.Elapsed.TotalMilliseconds);
//reset after instead of before of course
s.Reset();
您打印到控制台的是累计次数,不是平均次数,也不是个别次数。
我建议你像这样打印个人时间:
s.Start();
frs.Select(k[i]);
s.Stop();
var elapsed = (double)s.Elapsed.TotalMilliseconds;
avg = avg + elapsed; //it is really sum, not avg
s.Reset();
Console.WriteLine(elapsed);
我猜第一种方法的第一次迭代会消耗最多的时间,可能是因为JIT compilation。如果你打印个别时间,你会清楚地看到这一点。
另外,我建议你把变量名从avg
改成sum
,只计算循环后的平均值
一个小请求的单个样本受制于太多变数。
为了更好地了解性能,运行 每次执行几千次(比如 6000 次),然后丢弃前 1000 次左右的结果以消除任何预热因素(JIT/缓存等)。
将您的结果除以 5000 得到平均执行时间。这种方法将帮助您保持理智并更好地指示性能。