【问题标题】:will declaring variables inside sub-blocks improve performance?在子块中声明变量会提高性能吗?
【发布时间】:2023-03-18 02:26:01
【问题描述】:

在 C# 中,比较以下 三个 替代方案时,性能会有什么不同吗?

一个

void ONE(int x) {

if (x == 10) 
{
    int y = 20;
    int z = 30;
    // do other stuff
} else {
    // do other stuff
}
}

两个

void TWO(int x) {

int y;
int z;

if (x == 10) 
{
    y = 20;
    z = 30;
    // do other stuff
} else {
    // do other stuff
}
}

三个

void THREE(int x) {

int y = 20;
int z = 30;

if (x == 10) 
{
    // do other stuff
} else {
    // do other stuff
}
}

【问题讨论】:

  • 没有。您担心所谓的“微优化”:您是否进行了基准测试以确定您确实存在性能问题?
  • @Mitch:我在 Craig 的帖子中没有看到任何关于他的代码性能缓慢的抱怨。他有一个完全有效和聪明的问题要问,所以他做到了。就像我们不能发布任何涉及性能的@SO。
  • 我什至不会称之为微优化,而是纳米优化。任何看过分析器输出的人都知道,担心存储变量或调用函数所花费的时间是微不足道的。
  • @Igor:这不仅仅是执行速度,我对内存使用感兴趣,因为最终这也会影响性能。如果变量是长字符串,那么它可能很重要。
  • @devoured elysium:标题是“在子块中声明变量会提高性能吗?”看起来很简单......

标签: c# scope variable-declaration


【解决方案1】:

所有其他条件都相同(它们通常不是,这就是为什么您通常必须实际测试它的原因),ONE()TWO() 应该生成相同的 IL 指令,因为局部变量最终局限于整个方法。 THREE() 的速度会可以忽略不计如果x==10,因为其他两个不会费心将值存储在局部变量中。

所有三个都占用相同数量的内存——所有变量的内存都被分配,即使它们中没有存储任何东西。不过,如果 JIT 编译器曾经寻找未使用的变量,它可能会在此处执行优化。

【讨论】:

  • +1 表示 ONE 和 TWO 生成相同的 IL。 C#/CLR 中的方法级别作用域是一个偷偷摸摸的,尤其是对于 C++ 程序员。
  • 当 x != 10 时编译器还会在选项 ONE 中分配内存吗?
  • @Craig,是的,它会的——因为在设置函数调用(包括为变量分配内存)之后实际评估它之前,无法知道 x!=10 是否。
【解决方案2】:

没有性能差异,但您会发现每个示例之间的变量范围问题。

您还在这些示例之间展示了三种不同的意图,这不是您想要的:

  1. y 和 z 仅限于 if 语句的范围。

  2. y 和 z 在 if 语句之外使用,但有条件设置。

  3. y 和 z 与 if 语句无关。

【讨论】:

    【解决方案3】:

    当然,您应该始终选择 ONE,它更具可读性。它快了几分之一纳秒并不是偶然的,可读的代码通常是。

    【讨论】:

      【解决方案4】:

      我认为这不会有太大的不同。您唯一需要担心的是创建新对象并对其进行初始化是否代价高昂。您总是可以尝试对每种方法进行数千次分析,看看是否有任何差异,但我怀疑您会发现任何差异。

      我唯一一次将声明移离它使用的地方是它是否会在循环中处理。例如:

      void RunMethod() {
        FormRepresentation formRep = null;
        for (int idx = 0; idx < 10; idx++) {
          formRep = new FormRepresentation();
          // do something
        }
      }
      

      实际上并没有任何区别,因为对象仍在创建中,但对我来说,它看起来更干净。您需要考虑的另一件事是变量的范围。声明的变量不能在它们声明的范围之外使用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-14
        • 2019-09-30
        • 1970-01-01
        • 1970-01-01
        • 2018-04-14
        • 2011-12-14
        • 2017-06-27
        • 2013-04-12
        相关资源
        最近更新 更多