【问题标题】:Does putting less number of curly braces really helps?减少花括号的数量真的有帮助吗?
【发布时间】:2014-07-27 14:45:26
【问题描述】:

如果在 if 语句后不要使用花括号会怎样。喜欢:-

if(SomeCondition())
    return true;

代替

if(SomeCondition())
{
  return true;
}

在编译时间、更好的 IL 代码生成、占用更少的空间或任何其他方面(在这一点上我真的无法想到)方面,它真的对编译器有帮助吗?想知道它真的有帮助还是只是代码可读性?

【问题讨论】:

  • 它们是一样的。它们都生成相同的IL 代码。
  • 它们完全一样,大括号是必需的,除非你的条件结果只有一个语句长,所以跳过它们并不常见。
  • return SomeCondition(); 相同(就 IL 代码而言)但更易于阅读

标签: c# optimization compiler-construction clr


【解决方案1】:

他们也这样做。
如果您处于调试模式,MSIL 代码在这两种情况下几乎相同(感谢 Dirk)。
在发布模式下,MSIL 将是相同的。

这是一个 linqpad 示例(调试模式):

示例 1:
C#:

void Main()
{
    bool a = true;
    int i;
    if(a)
     i = 17;  
}

IL:

IL_0001:  ldc.i4.1    
IL_0002:  stloc.0     // a
IL_0003:  ldloc.0     // a
IL_0004:  ldc.i4.0    
IL_0005:  ceq         
IL_0007:  stloc.2     // CS$4$0000
IL_0008:  ldloc.2     // CS$4$0000
IL_0009:  brtrue.s    IL_000E
IL_000B:  ldc.i4.s    11 
IL_000D:  stloc.1     // i

示例2:

C#:

void Main()
{
    bool a = true;
    int i;
    if(a)
    {
     i = 17;  
    }
}

IL:

IL_0001:  ldc.i4.1    
IL_0002:  stloc.0     // a
IL_0003:  ldloc.0     // a
IL_0004:  ldc.i4.0    
IL_0005:  ceq         
IL_0007:  stloc.2     // CS$4$0000
IL_0008:  ldloc.2     // CS$4$0000
IL_0009:  brtrue.s    IL_0010
IL_000B:  nop         
IL_000C:  ldc.i4.s    11 
IL_000E:  stloc.1     // i

【讨论】:

  • 不同之处在于您可能使用了调试模式进行编译。在发布模式下,nop 不会被发出。
  • 有趣的部分:MSIL 代码的大小是运行时因素,而不是编译时间因素。就创建 IL 所需的 cpu 周期而言,使用带大括号的发布应该更长,因为词法分析器会解析额外的大括号,并且发布优化可能(如果发出 NOP)需要压缩额外的指令(NOP)
  • @Samuel 插入 NOP 是为了帮助调试(最值得注意的是,设置断点以阻止启动和编辑并继续)。它们根本没有添加到发布版本中。当然,如果你在编译时间上的调整归结为空的括号,那么你可能已经太深了。
【解决方案2】:

生成的代码完全没有区别,至少在发布模式下没有。在调试模式下,可能会添加更多nop 指令,因此每行至少有一条指令,以便您在调试代码时可以单步执行。

编译时间自然会有所不同,因为代码并不相同。但是,这种差异是如此之小,以至于您需要数百万行代码才能注意到差异。

您应该使用使代码更易于维护的那个。如果您的代码风格导致您犯了错误,那么修复一个错误所花费的时间将超过您在编译中可以节省的总时间。


就我个人而言,即使代码块中只有一条语句,我也更喜欢始终将括号放在此处。如果代码遵循单一模式而不是两种不同的模式,则根据情况更容易阅读代码。

【讨论】:

    【解决方案3】:

    从技术上讲你是对的,因为工具链的词法分析器部分不需要解析那些额外的标记,但区别在于几个 CPU 周期,所以你不会注意到这一点,我建议总是使用大括号。

    编辑:正如其他人指出的那样:代码将是相同的。如果您阅读 C#(以及 C、C++、Java 等其他一些语言)的语法规范,那么您会看到 if 条件后跟 statement,而不是多个语句。为了能够为 if 条件编写多个语句,您将需要花括号。 当你在返回之前额外记录一些东西或做一些事情时,你不得不使用大括号。

    对于您的情况,MSIL 代码恕我直言 may 看起来相同,但这不能保证。因为编译器可以随意添加NOP IL-commands,只要编译器感觉如此。但是,您的代码的语义不会改变。

    长话短说:您的样本在语义上是等价的。

    【讨论】:

    • 为什么建议总是使用大括号?我没有,而且我真诚地认为,在诸如 OP 发布的场景中,省略大括号使其更具可读性。
    • 好的,如果可能的话,请支持我的问题!因为我想这个问题真的很有意义!
    • 另外,在堆叠多个using 语句时省略大括号非常好! 有助于提高可读性。
    • 我同意@dcastro 的观点,对于非常简单的语句,省略大括号通常更具可读性(因为它们实际上只是噪音)。然而,有些人总是使用它们的原因是,以防其他人在if 部分添加一些代码并忘记添加花括号......但如果他们忘记了这一点,可能还有更多需要担心的事情。 ;)
    • 因为我的上下文是 C++,并且有一个 MISRA C 14.9 和 MISRA C++ 6-4-1 的编码指南。我们也遇到过一些讨厌的代码,其中没有大括号的语句被扩展而不添加大括号导致odd 代码:)(这只是我的建议,这当然值得商榷)
    【解决方案4】:

    就编译时间而言,它们都是等效的。这真的归结为个人喜好的问题。一般来说,我喜欢为除 return 语句之外的所有内容包括大括号,即 if(condition) { do something } else return x;

    【讨论】:

      猜你喜欢
      • 2014-08-21
      • 1970-01-01
      • 2018-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多