【问题标题】:Calculation time differences in loops循环中的计算时间差
【发布时间】:2012-11-08 23:01:27
【问题描述】:

在编写我目前正在处理的程序时,我注意到性能发生了一些变化,并想检查我用来解释这一点的某些循环中的计算时间。

我编写了一个非常简单的程序,它在一个循环中执行一个简单的加法计算并输出它所花费的时间,我注意到目前有两个对我来说无法解释的效果。

首先是代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        int a = 1, b = 2, c = 0;

        Stopwatch sw = new Stopwatch();

        sw.Start();
        for (int i = 0; i < 100; i++)
        {
            c += (a + b);
        }
        sw.Stop();
        c = 0;
        textBlock1.Text = 100 + ": " + sw.ElapsedTicks;

        sw.Restart();
        for (int i = 0; i < 1000; i++)
        {
            c += (a + b);
        }
        sw.Stop();
        c = 0;
        textBlock2.Text = 1000 + ": " + sw.ElapsedTicks;

        sw.Restart();
        for (int i = 0; i < 10000; i++)
        {
            c += (a + b);
        }
        sw.Stop();
        c = 0;
        textBlock3.Text = 10000 + ": " + sw.ElapsedTicks;

        sw.Restart();
        for (int i = 0; i < 1000000; i++)
        {
            c += (a + b);
        }
        sw.Stop();
        c = 0;
        textBlock4.Text = 1000000 + ": " + sw.ElapsedTicks;

        sw.Restart();
        for (int i = 0; i < 100000000; i++)
        {
            c += (a + b);
        }
        sw.Stop();

        textBlock5.Text = 100000000 + ": " + sw.ElapsedTicks;
    }
}

现在我可以观察到以下内容:

  1. 第一次启动程序点击按钮并计算后,100 的短循环大约需要两倍/三倍(6-9 滴答),只要我第二次运行它(2-4 )。之后,它将保持大约相同的长度(2-4 个滴答声)。

  2. 循环时间之间存在奇怪的比例,当我继续单击按钮时,这些比例保持不变,大致如下:

    • 100:3
    • 1000:15
    • 10000:150
    • 1000000:17000
    • 100000000: 840000

有没有解释为什么 100 循环需要大约 1000 循环的 1/5 时间,即使它是计算量的 1/10 倍,以及为什么 100 Mio.循环只需要大约 1 Mio 的 50 倍。循环,即使它是计算量的 100 倍? 有没有人知道为什么我在启动程序后运行一次计算后时间(尤其是 100 循环)会发生变化,然后保持不变?

【问题讨论】:

    标签: c# wpf loops time sum


    【解决方案1】:

    有没有解释为什么 100 循环需要大约 1000 循环时间的 1/5,即使它是计算次数的 1/10 倍

    您正在测量三个滴答声,这是非常非常短的时间。如果您碰巧遇到了上下文切换,您可能会损失更多的时间,即使您的线程被立即再次安排。即使使用Stopwatch,也基本上没有足够多的时间来进行明智的测量。

    有人知道为什么我在启动程序后运行一次计算后时间(尤其是 100 循环)会发生变化,然后保持不变?

    我的猜测是它与 JIT 编译和/或垃圾收集有关。

    这就是为什么通常基准测试首先运行“预热”轮,并且他们测试合理的工作量,以便测试将花费合理的时间,平滑时间上的小颠簸。

    【讨论】:

    • 感谢您的快速答复。是的,100 循环非常短。但比较 100 Mio。循环和 1 Mio。循环是否应该在某种程度上具有可比性?特别是因为其他的(1000、10000 和 1 Mio.)在时间上似乎是相当线性的。
    • @phil13131:即使在 1,000,000 的情况下,您仍然只能测量 1.7 毫秒。各种事情都会影响该级别的性能。我通常不相信任何运行时间少于一秒的基准测试 - 最好更长。
    • 好吧,我就照原样接受。我只是对这个突然的“碰撞”感到惊讶,我认为实际上是一个很长的循环。感谢您指出 JIT 编译器,但是,我认为它会在执行按钮之前编译按钮的整个方法,因此它应该不会真正产生影响。
    猜你喜欢
    • 2019-06-17
    • 2021-12-04
    • 1970-01-01
    • 2018-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-02
    相关资源
    最近更新 更多