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 得到平均执行时间。这种方法将帮助您保持理智并更好地指示性能。