0
            Stopwatch sw = new Stopwatch();
            for (int i = 0; i < lines.Length; i++)
            {
                sw.Start();
                fn(); //call function
                sw.Stop();

            }
            Console.WriteLine(sw.ElapsedMilliseconds);


            long total =0;
            for (int i = 0; i < lines.Length; i++)
            {
                Stopwatch sw = Stopwatch.StartNew();
                fn(); //call function
                sw.Stop();
                total += sw.ElapsedMilliseconds;

            }
            Console.WriteLine(total);

输出不一样,你有什么解释吗?

4

4 回答 4

8

撇开诸如您在第二个循环中创建大量对象的事实不谈,这很容易导致内部垃圾收集fn()或其他东西实际上使其在计时时花费更长的时间,您也只是在每次迭代中花费了经过的毫秒数第二种情况。

假设每次迭代需要 0.1 毫秒。第二个循环的总数将为 0,因为在每次迭代中,它会将经过的时间四舍五入为 0 毫秒。第一个循环跟踪经过的刻度

撇开这一切不谈,无论如何,您都不应该如此频繁地启动和停止计时器 - 它弄乱您的结果。相反,在循环之前启动秒表一次,并在循环之后停止它。

如果您想消除循环的开销,只需计时一个循环以找到开销,然后从包含实际工作的循环所花费的时间中减去该开销。现在它并不是那么简单,因为现实世界 CPU 的各种复杂性——比如缓存未命中——但坦率地说,微基准测试在这方面从来都不是特别准确。它应该被用作指南而不是其他任何东西。

于 2010-11-03T15:45:23.920 回答
4

因为StartNew()Stop()产生开销。这就是您通常使用 100 或 1000 次迭代进行此类测试的原因:以最大限度地减少实际性能测量的性能开销。

于 2010-11-03T15:37:45.060 回答
1

您可能遇到了系统计时器的粒度。有时计时一个微不足道的函数会返回 0 或 10 毫秒。此错误可能会在您的测试中增加。

如果您运行第一个循环两次或第二个循环两次,您可能会看到类似的结果。

于 2010-11-03T15:42:17.633 回答
1

循环的开销将大大小于重复停止/启动计时器的开销,甚至在重复创建新计时器的情况下更小。因此,我会在循环之前启动计时器并在循环之后结束它,并将您的经过时间除以迭代次数。它会给你更准确的结果。

于 2010-11-03T15:44:52.637 回答