代码之家  ›  专栏  ›  技术社区  ›  Ahmed

秒表奇怪的行为

  •  0
  • Ahmed  · 技术社区  · 15 年前
                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 回复  |  直到 13 年前
        1
  •  8
  •   Jon Skeet    13 年前

    将诸如在第二个循环中创建大量对象这样的事情放在一边,这很容易导致内部的垃圾收集 fn() 或者别的什么 事实上 让它花更长的时间计时,你也只是在花时间 毫秒 第二种情况下的每个迭代。

    假设每次迭代需要0.1毫秒。第二个循环的总计将为0,因为在每次迭代中,它将所用时间四舍五入为0毫秒。第一个循环跟踪经过的 蜱类 .

    把这些都放在一边,无论如何你不应该频繁地启动和停止计时器-它 把结果搞砸了。相反,在循环之前启动一次秒表,在循环之后停止秒表。

    如果你想去掉循环的开销,只需在 空的 循环查找开销,并从包含实际工作的循环所花费的时间中减去开销。现在不是真的 相当地 这很简单,因为现实世界中CPU的各种复杂性(比如缓存未命中),但是微标记是坦率的。 从未 在这方面尤其准确。它应该比其他任何东西都更适合作为指南。

        2
  •  4
  •   Pieter van Ginkel    15 年前

    因为 StartNew() Stop() 产生间接费用。这就是您通常使用100s或1000s迭代进行这些测试的原因:为了最小化实际性能度量的性能开销。

        3
  •  1
  •   Dennis Burton    15 年前

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

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

        4
  •  1
  •   spender    15 年前

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

    推荐文章