代码之家  ›  专栏  ›  技术社区  ›  Sebastian Gray

如果所有这些操作都必须发生,那么在一行中编写一组操作有什么好处吗?

  •  1
  • Sebastian Gray  · 技术社区  · 15 年前

    从编译后的角度(而不是从编码语法的角度),在C中,在编译后的代码中,在一行上发生的一组操作与在多行上发生的一组操作之间是否存在实际差异?

    这个

    object anObject = new object();
    anObject = this.FindName("rec"+keyPlayed.ToString());
    Rectangle aRectangle = new Rectangle();
    aRectangle = (Rectangle)anObject;
    

    与此相反。

    Rectangle aRectangle = (Rectangle)this.FindName("rec"+keyPlayed.ToString());
    

    我想知道的是,似乎有一种观点认为,使用的最少的行数更好,但是我想了解这是否是因为有有形的技术利益,或者是否在某个时候有有形的利益,或者是否确实是因为一个可量化的原因?

    6 回复  |  直到 15 年前
        1
  •  9
  •   Marc Gravell    15 年前

    行数无关紧要;如果代码是等效的(您的 不是 )

    实际上,除非我们知道 FindName 返回,我们无法正确回答-因为通过强制转换 object 您可能正在引入“box”操作,并且您可能正在更改 转换 将操作(或可能是被动的无操作强制转换)转换为主动的双强制转换(强制转换为 对象 铸成 Rectangle )现在,我假设 发现名 收益率 对象 ,为了简单起见。如果你曾经用过 var ,我们一眼就知道您的代码没有改变类型(box/cast/etc):

    var anObject = this.FindName("rec"+keyPlayed.ToString());
    

    在发布模式下(启用了优化),编译器将删除大多数已设置的变量,然后立即使用。上面两行的最大区别是第二个版本不会创建和丢弃 new object() new Rectangle() . 但是如果您没有这样做,代码将是等效的(再次假设 发现名 收益率 对象 ):

    object anObject;
    anObject = this.FindName("rec"+keyPlayed.ToString());
    Rectangle aRectangle;
    aRectangle = (Rectangle)anObject;
    

    如果重新使用变量(在这种情况下,编译器不一定会删除它),并且如果该变量被lambda/anon方法“捕获”,或者在 ref / out . 如果编译器/jit选择只在寄存器中执行操作,而不将其复制回变量(寄存器的宽度不同(更大),即使对于“固定大小”的数学,例如 float )

        2
  •  2
  •   Charlie Gevious    15 年前

    我认为您通常应该力求使代码尽可能可读,有时这意味着将代码分开,有时这意味着将代码放在一行上。以可读性为目标,如果性能成为问题,请使用分析工具分析代码,并在必要时对其进行重构。

        3
  •  1
  •   tchen    15 年前

    编译后的代码可能没有任何区别(可能启用了优化),但也要考虑可读性:)

    在您的示例中,一行上的所有内容实际上比单独的行更可读。你想做的事情很明显。但其他人可以迅速指出反例。所以用你的判断力来决定该走哪条路。

        4
  •  1
  •   sharptooth    15 年前

    有一个重构模式 prefer a call to a temporary variable . 遵循此模式减少了代码行数,但使交互式调试更加困难。

        5
  •  1
  •   AnthonyLambert    15 年前

    一是两者的主要现实问题是, 调试时,在不同的行上使用单个步骤,并将结果传递给局部变量可能很有用。

    这意味着您可以清楚地单步执行代码的不同位,这些位给出最终结果并查看中间值。

    当您构建优化后,编译器将删除这些步骤并使代码高效。

    托尼

        6
  •  0
  •   Guffa    15 年前

    在您的示例中,有一个实际的区别,因为您在第一段代码中创建的是不使用的对象和值。

    编写代码的正确方法如下:

    object anObject;
    anObject = this.FindName("rec" + keyPlayed.ToString());
    Rectangle aRectangle;
    aRectangle = (Rectangle)anObject;
    

    现在,它和单行版本的区别在于,您要声明更多的局部变量。在大多数情况下,编译器可以对其进行优化,使生成的代码无论如何都是相同的,即使它在生成的代码中实际使用了一个以上的局部变量,与您在该代码中所做的任何其他操作相比,这仍然是可忽略的。

    对于这个例子,我认为单行版本更清晰,但是对于更复杂的代码,将其分为几个阶段当然更清晰。局部变量非常便宜,因此如果代码变得更清晰,您应该毫不犹豫地使用一些变量。