c# - 在 for 循环内声明的变量会影响循环的性能吗?

标签 c# for-loop variable-declaration

我做了功课,发现反复保证无论在 for 循环内部还是外部声明变量都不会影响性能,而且它实际上编译为完全相同的 MSIL。但我一直在摆弄它,发现在循环内移动变量声明确实会带来相当大且一致的性能提升。

我编写了一个小型控制台测试类来测量这种效果。我初始化了一个静态 double[] 数组 items, 并且两个方法对其执行循环操作,将结果写入静态 double[] 数组缓冲区。 最初,我的方法是那些我注意到差异的方法,即复数的大小计算。对长度为 1000000 的 items 数组运行 100 次,对于变量(6 个 double 变量)在循环内的那个,我的运行时间始终较低:例如,32,83±0,64 ms v 43,24±0,45 ms 在使用 Intel Core 2 Duo @2.66 GHz 的旧配置上。我尝试以不同的顺序执行它们,但这并没有影响结果。

然后我意识到计算复数的大小远不是一个最小的工作示例,并测试了两种更简单的方法:

    static void Square1()
    {
        double x;

        for (int i = 0; i < buffer.Length; i++) {
            x = items[i];
            buffer[i] = x * x;
        }
    }


    static void Square2()
    {
        for (int i = 0; i < buffer.Length; i++) {
            double x;
            x = items[i];
            buffer[i] = x * x;
        }
    }

通过这些,结果以另一种方式出现:在循环外声明变量似乎更有利:Square1() 为 7.07±0.43 ms v Square2( 为 12.07±0.51 ms )

我对ILDASM不熟悉,但是我已经把这两种方法拆解过了,唯一的区别似乎是局部变量的初始化:

      .locals init ([0] float64 x,
       [1] int32 i,
       [2] bool CS$4$0000)

Square1() v

      .locals init ([0] int32 i,
       [1] float64 x,
       [2] bool CS$4$0000)

Square2() 中。根据它,一个是STLoc.1,另一个是STLoc.0,反之亦然。在更长的复杂幅度计算 MSIL 代码中,甚至代码大小也不同,我在外部声明代码中看到了 STLoc.s i,而在内部声明中有 STLoc.0代码。

那怎么可能呢?我是在忽略某些东西还是真正的效果?如果是,它会对长循环的性能产生重大影响,因此我认为值得讨论。

非常感谢您的想法。

编辑:我忽略的一件事是在发布之前在几台计算机上对其进行测试。我现在已经在 i5 上运行了它,这两种方法的结果几乎相同。我很抱歉发布了这样一个误导性的观察结果。

最佳答案

任何称职的 C# 编译器都会为您执行此类微优化。仅在必要时将变量泄漏到作用域之外。

因此,如果可能,请将 double x; 保留在循环内部。

但就个人而言,如果 items[i] 是普通旧数据数组访问,那么我会写 buffer[i] = items[i] * items[i];。 C 和 C++ 会对此进行优化,但我认为 C# 不会(还);您的反汇编意味着它没有。

关于c# - 在 for 循环内声明的变量会影响循环的性能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42140012/

相关文章:

c++ - "void()"有什么用?

Javascript:多个变量声明 - 变量何时可用?

c# - 使用 log4net Asp.net Core 2.2 将日志文件写入 AppData 不起作用

c# - 将一个方法作为参数传递给另一个方法

c# - 仅使用 XAML 来防止在 TextBox 中输入字符

c - 如何在 C 中将 double 组转换为整数数组?

css - 显示没有空格的缩略图的最简单方法

c# - 'CrystalDecisions.CrystalReports.Engine.ReportDocument' 的类型初始值设定项抛出异常

c - 为什么程序不执行最终的 printf 语句?

c++ - 在 for 循环中重新声明对象 - C++