C# 在预调用后,在时间测量方面运行得更快

本文关键字:运行 方面 测量 时间 调用 | 更新日期: 2023-09-27 18:31:37

我只是想找出为什么函数在测量时间之前被调用一次后似乎运行得更快。

以下是我的测量代码示例:

            float X = 0;
        FastMath.FireUp(); // Does nothing in this sample
        Stopwatch watch = new Stopwatch();
        watch.Start();
        for (int i = 0; i < 5; i++)
        {
            X = FastMath.FastSin(i);
        }
        watch.Stop();
        Console.WriteLine("TIME : " + watch.Elapsed );

在这里你可以看到我调用的函数:

        public static float FastSin(float val)
    {
        int index = 360 - ((int)val % 360);
        if(index == 360)
        {
            return 0;
        }
        return -TRIGONOMETRIC_LOOKUPTABLE[index];
    }

所以问题是,我的测量显示以下输出:

时间 : 00:

00:00.0001196

让我们用以下内容填充"FireUp"函数:

float x = FastSin(123);

现在测量时间显着减少:

00:00

:00.0000015

但是,在FireUp函数中没有调用的"FastCos"仍然需要更长的时间。

我应该提到的另外两点:

  • 如果我不调用"FireUp"函数,时间会再次增加:
    时间 : 00:00

    :00.0002796

  • 如果我用以下方法填充我的"FireUp"功能:

    浮点数 x = 快罪(123);x = 快速余量(123);

    在未来的测量中,它对于这两个功能都运行良好。现在每个函数都需要 TIME : 00:00:00.0000019。

为什么会这样?

C# 在预调用后,在时间测量方面运行得更快

编译为托管代码时,编译器会翻译源代码 编码为Microsoft中间语言 (MSIL),这是一种 独立于 CPU 的指令集,可有效转换 到本机代码。

在运行时编译(由 JIT)的 MSIL 代码依赖于二进制平台的代码。CLR 编译仅使用的代码包,然后它将在第一次调用之前编译FastSin方法。

运行时提供另一种称为安装时的编译模式 代码生成。安装时代码生成模式转换 MSIL 与常规 JIT 编译器一样转换为本机代码,但它会转换 一次更大的代码单元,存储生成的本机代码 在随后加载和运行程序集时使用。

可以阅读有关 MSIL 和将 MSIL 编译为本机代码的详细信息。

该方法是及时编译的(jit)。 这就是为什么它已经被调用后更快。