作为一个简单的示例,请考虑以下(人为的)示例:
double Mean(List<double> items)
{
double mu = 0;
foreach (double val in items)
mu += val;
return mu / items.Length;
}
我们可以这样计时:
void DoTimings(int n)
{
Stopwatch sw = new Stopwatch();
int time = 0;
double dummy = 0;
for (int i = 0; i < n; i++)
{
List<double> items = new List<double>();
// populate items with random numbers, excluded for brevity
sw.Start();
dummy += Mean(items);
sw.Stop();
time += sw.ElapsedMilliseconds;
}
Console.WriteLine(dummy);
Console.WriteLine(time / n);
}
如果项目列表实际上非常大,则此方法有效。但如果它太小,我们将不得不在一个时间里进行多次运行:
void DoTimings(int n)
{
Stopwatch sw = new Stopwatch();
int time = 0;
double dummy = 0;
List<double> items = new List<double>(); // Reuse same list
// populate items with random numbers, excluded for brevity
sw.Start();
for (int i = 0; i < n; i++)
{
dummy += Mean(items);
time += sw.ElapsedMilliseconds;
}
sw.Stop();
Console.WriteLine(dummy);
Console.WriteLine(time / n);
}
在第二个例子中,如果列表的大小太小,那么我们可以通过简单地运行这个足够大的n
. 虽然每个都有它的优点和缺点。
但是,在执行其中任何一项之前,我会事先进行“热身”计算:
// Or something smaller, just enough to let the compiler JIT
double dummy = 0;
for (int i = 0; i < 10000; i++)
dummy += Mean(data);
Console.WriteLine(dummy);
// Now do the actual timing
两者的另一种方法是按照@Rig 在他的回答中所做的,并建立一个结果列表来进行统计。在第一种情况下,您只需建立每个单独时间的列表。在第二种情况下,您将建立一个多次运行的平均时间列表,因为计算时间可能小于秒表中最细粒度的时间。
说了这么多,我想说所有这一切都有一个非常大的警告:计算某件事运行所需的时间很难正确完成。想要进行分析是令人钦佩的,但是你应该对 SO 做一些研究,看看其他人做了什么来正确地做到这一点。编写一个计时很糟糕的例程很容易,但很难做到正确。