我正在使用System.Diagnostics.Stopwatch
为my program中的两个单独操作计时。
程序找到所有素数,直到用户输入数字。
当我给它一个大的输入,例如100,000时,它报告已经完成了两个操作中的每一个,每个操作在3毫秒内完成。我知道我编写的算法非常有效,但我怀疑它只需要3毫秒。
有时,两个操作中的每个操作都需要很长时间,但是随着时间的推移,仍会打印非常少的毫秒数。
这让我怀疑我的分析代码中有什么问题。你能否告诉我秒表是否报告了正确的时间?如果是的话,为什么我有时会看到探测器输出仅在很长一段时间后出现?
答案 0 :(得分:2)
由于FindPrimesTill
仅构建"查询" (IEnumerable
)并且此查询仅在调用primesTillN.Count()
时执行(或强制立即执行的任何其他方法),您应该在stopwatch.Stop()
后移动primesTillN.Count()
并且在'我会得到正确的结果。
答案 1 :(得分:1)
我正在编写这个答案,以供我自己参考链接到github代码。
我的初始代码如下:
static void Main(string[] args)
{
int n = 0;
Console.WriteLine("This program prints all prime numbers till a number you specify.\n");
Console.Write("Find primes till which number? ");
var b = int.TryParse(Console.ReadLine(), out n);
if (!b) return;
var stopwatch = new Stopwatch();
stopwatch.Start();
var primesTillN = FindPrimesTill(n);
stopwatch.Stop();
var millisecondsToFind = stopwatch.ElapsedMilliseconds;
var numFound = primesTillN.Count();
Console.WriteLine($"\n{numFound} primes between 1 and {n}. Time taken to find primes: {millisecondsToFind} milliseconds");
Console.WriteLine("Printing...\n");
stopwatch.Reset();
stopwatch.Start();
primesTillN.Print();
stopwatch.Stop();
var millisecondsToPrint = stopwatch.ElapsedMilliseconds;
Console.WriteLine($"\n\nSTATS:\nTime to find {numFound} primes between 1 to {n}: {millisecondsToFind} milliseconds.");
Console.WriteLine($"Time taken to print: {millisecondsToFind} milliseconds.\n");
Console.ReadKey();
}
正如Aleksey正确指出的那样,我的代码中有两个错误:
由于方法FindPrimesTill
返回了一个懒惰评估的IEnumerable<T>
,因此秒表只计算构建查询的时间。
static void Main(string [] args) { ...
stopwatch.Start();
var primesTillN = FindPrimesTill(n);
stopwatch.Stop();
var millisecondsToFind = stopwatch.ElapsedMilliseconds;
var numFound = primesTillN.Count();
...
}
这两个修复中的一个可以在这里起作用:
static void Main(string[] args)
{
...
stopwatch.Start();
var primesTillN = FindPrimesTill(n);
// Put the call to IEnumerable<T>.Count before
// stopping the stopwatch.
// Since Count() is a greedy operator,
// it would have executed the query.
var numFound = primesTillN.Count();
stopwatch.Stop();
var millisecondsToFind = stopwatch.ElapsedMilliseconds;
...
}
或者:
static void Main(string[] args)
{
...
stopwatch.Start();
// Eagerly evaluate the IEnumerable returned
// by FindPrimesTill by converting it into a List<T>
var primesTillN = FindPrimesTill(n).ToList();
stopwatch.Stop();
var millisecondsToFind = stopwatch.ElapsedMilliseconds;
var numFound = primesTillN.Count;
...
}
我的代码中的第二个错误是,当我应该在第二个实例中打印出millisecondsToFind
以计算millisecondsToPrint
方法调用时,我打印出变量IEnumerable<T>.Print
static void Main(string [] args) { ...
Console.WriteLine($"Time taken to print: {millisecondsToFind} milliseconds.\n");
Console.ReadKey();
}
应该是:
static void Main(string[] args)
{
...
Console.WriteLine($"Time taken to print: {millisecondsToPrint} milliseconds.\n");
Console.ReadKey();
}