【问题标题】:Defining a variable inside a loop vs outside在循环内部与外部定义变量
【发布时间】:2012-12-02 17:35:07
【问题描述】:

我想知道在每一对循环代码中,某个版本是否比第二个版本消耗更少的内存,以及在某些版本中我们是否确实在每个循环周期中为变量分配了新空间。

注意:2 很明显,1 和 3 更有趣..

1

While(!exit)
{
  int x = 5;
}

对比:

int x= 0;
While(!exit)
{
  x = 5;
}

引用类型的相同问题: 2

While(!exit)
{
      Point p = new Point();
      p.x = 5;
}

对比:

Point p = new Point();
While(!exit)
{
      p.x = 5;
}

3。没有分配的引用类型类似于1?:

While(!exit)
{
      Point p = point1;
}

对比:

Point p = null;
While(!exit)
{
   p = point1;
}

【问题讨论】:

  • 我认为编译器会为你优化它。
  • 出于所有实际目的,这并不重要。使用范围作为变量声明决策的基础,而不是性能。
  • 顺便说一句:点是struct,所以值类型。
  • 假设 Point 是我写的,它是一个类
  • 是值类型(struct)还是引用类型(class),与问题无关。两种情况都有存储要求。对于值类型,存储要求是该类型的完整存储要求。在引用类型的情况下,存储要求是引用(x86 为 4 字节,x64 为 8 字节)。

标签: c# memory memory-management


【解决方案1】:

没关系。编译器对其进行了优化,因此它保持不变。在 C# 等编译语言中,它根本不应该影响性能。例如,在 Java 中,最好只声明一次。

【讨论】:

    【解决方案2】:

    正确的判断方法是反汇编,看代码。您会看到对每个的引用。

    链接到 MSDN 方法:http://msdn.microsoft.com/en-us/library/f7dy01k1.aspx

    代码在 CIL 中非常易读。只要搜索函数名,就会看到对new等的调用。

    【讨论】:

    • 对 C# 的优化倾向于在抖动级别进行,而不是在 IL 级别进行。最重要的是,这实际上并没有回答问题。
    【解决方案3】:

    编译器决定您的函数需要多少堆栈存储位置,并将尽其所能减少这种需求。比如:

    {
       int a;
       ...
    }
    {
       int b;
       ...
    }
    

    似乎需要两个存储位置,但编译器可以看到第一个永远不会在第一个范围之外使用,并且可以将位置重新用于 b。

    它还可以看到它可以完全取消堆栈存储并在寄存器中执行整个操作。

    无论是否循环,单个变量声明定义一个存储位置。永远不会为循环的每次迭代创建一个新的存储位置。

    一般来说,这不是您需要关心的事情。

    请注意,“调试”构建可能会在堆栈上为声明的每个变量生成单独的存储位置,以便在调试时更轻松地查看这些变量。

    【讨论】:

      猜你喜欢
      • 2017-01-05
      • 1970-01-01
      • 2012-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 2021-08-20
      相关资源
      最近更新 更多