不必要的花括号会降低性能吗?

在编程之后最近遇到这个问题,我一直在想这个。 以下是两个合法和编译的片段。 具体来说,我的问题是这个..在第二种情况下,括号是否使程序变慢? 为什么允许这样做呢?

第一例:

if (statement) { // do something } 

第二个案例:

 { if (statement) { // do something } } 

另外如果我有类似下面的代码的话。运行时是否与调用函数X相同而没有任何大括号。

 { { { // call function X } } } 

大多数情况下,它没有任何区别 – 你应该为可读性编写代码而不是其他任何东西。

然而,花括号可以以惊人的方式对性能产生影响,尽管这很不寻常。 考虑以下代码:

 using System; using System.Collections.Generic; class Test { static void FewerCurlies() { List actions = new List(); for (int i = 0; i < 100; i++) { int x; if (i % 3 == 0) { actions.Add(() => x = 10); } int y; if (i % 3 == 1) { actions.Add(() => y = 10); } } } static void MoreCurlies() { List actions = new List(); for (int i = 0; i < 100; i++) { { int x; if (i % 3 == 0) { actions.Add(() => x = 10); } } { int y; if (i % 3 == 1) { actions.Add(() => y = 10); } } } } } 

MoreCurlies的额外括号看起来多余,对吗? 不完全……生成的代码看起来更像是这样的:

 using System; using System.Collections.Generic; class Test { static void FewerCurlies() { List actions = new List(); for (int i = 0; i < 100; i++) { FewerCurliesCapture capture = new FewerCurliesCapture(); if (i % 3 == 0) { actions.Add(capture.Method1); } if (i % 3 == 1) { actions.Add(capture.Method2); } } } static void MoreCurlies() { List actions = new List(); for (int i = 0; i < 100; i++) { { MoreCurliesCapture1 capture = new MoreCurliesCapture1(); if (i % 3 == 0) { actions.Add(capture.Method); } } { MoreCurliesCapture1 capture = new MoreCurliesCapture2(); if (i % 3 == 1) { actions.Add(capture.Method); } } } } private class FewerCurliesCapture { public int x; public int y; public void Method1() { x = 10; } public void Method2() { y = 10; } } private class MoreCurliesCapture1 { public int x; public void Method() { x = 10; } } private class MoreCurliesCapture2 { public int y; public void Method() { y = 10; } } } 

这里的区别是:

  • 捕获类的实例在FewerCurlies的循环的每次迭代中FewerCurlies ,即使它未被使用
  • FewerCurlies中使用的捕获类的每个实例都包含两个变量,即使每个委托实际上只使用其中一个,而在MoreCurlies每个捕获类仅捕获一个变量

这有点特定于实现,但它表明冗余外观可以产生影响。

与此类问题一样,答案在于它产生的IL。 对于以下代码示例:

 public int X() { { { { return 0; } } } } public int Y() { return 0; } 

我们最终得到以下编译的IL:

 .method public hidebysig instance int32 X() cil managed { // Code size 2 (0x2) .maxstack 8 IL_0000: ldc.i4.0 IL_0001: ret } // end of method SomeType::X .method public hidebysig instance int32 Y() cil managed { // Code size 2 (0x2) .maxstack 8 IL_0000: ldc.i4.0 IL_0001: ret } // end of method SomeType::Y 

它们完全相同。 所以不,它对性能没有影响。 X读起来很可怕,但这是另一个问题。

Update {}会影响变量的范围,因此可能会产生影响。 再次,让我们检查一下:

 public int X() { var i = 1; { { i++; { return i; } } } } public int Y() { var i = 1; i++; return i; } 

再一次,IL产生的是相同的:

 // Code size 8 (0x8) .maxstack 2 .locals init ([0] int32 i) IL_0000: ldc.i4.1 IL_0001: stloc.0 IL_0002: ldloc.0 IL_0003: ldc.i4.1 IL_0004: add IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: ret 

但是,如果在闭包中捕获变量,它确实会影响事物。 在以下情况中, X确实会创建更多IL,这会对性能产生影响:

 public Func X() { { var i = 1; { i++; { return () => i; } } } } public Func Y() { var i = 1; i++; return () => i; } 

简短的回答是“不,他们不会降低绩效”。

编译器需要使用大括号来确定变量的范围,并知道当前语句组的结束位置。 一旦编译器完成处理,带有和不带有不必要的花括号的代码将产生相同的输出。

请注意,这与编译代码的性能有关,而与编译器本身的性能无关。 编译器将花费额外的时间来编译代码,因为输入的原始大小更大。 然而,为了使这个额外的时间变得可测量,不必要的括号的数量需要相当极端。

与C ++不同,在C ++中,当变量进入或超出范围时,可能需要编译器生成代码,C#中的大多数变量都被有效地提升到封闭的函数级范围。 代码:

 void foo() { { int i; ... stuff using i as int } { char i; ... stuff using i as char } } 

将有效地变成:

 void foo() { int i__1; char i__2; ... stuff using i__1 as int ... stuff using i__2 as char } 

使用第一个支撑部分的代码使用第一个变量i__1无论它在哪里使用i ,使用i__2第二个代码。 在某些情况下,在多个作用域块中声明具有相同名称和用途的变量可能会产生比在外部作用域中声明具有该共同目的的变量更低效的代码,但它很少会产生有意义的影响。 在大多数情况下,即时编译器将能够确定代码中的多个变量可以安全地映射到同一存储位置,甚至在那些不能满足一些额外变量所需的存储的情况下也是如此。非常影响性能。

没有花括号不会降低性能。

它有助于深入了解代码并提供良好的代码格式。 但是一些花括号是强制性的,如函数开始/结束,循环开始/结束,条件开始/结束,这个条件也有助于理解变量scrop。

假设您没有嵌套变量,使用不必要的花括号,只会在将代码转换为字节代码或机器代码时向标签表添加标签。 所以更糟糕的是构建时间会变慢。 如果嵌套中有变量,如果它们是没有破坏代码的基元但是如果你在嵌套大括号中创建了对象,那么你仍然不应该有问题,那么需要更好地理解GC,但我强烈怀疑任何明显的差异都会出现。 在所有情况下,因为编译器通过在构建项目时将引用存储在查找表中来执行额外的工作,所以在构建项目时会有一个(尽管可能不明显)延迟。

它不会导致任何性能下降,但使用大括号肯定会增加代码的可读性。 在真正的单词场景中,当您进行同行代码审查或配对编程时,您编写的内容将非常清晰和可读。

浏览以下链接

http://www.c-sharpcorner.com/UploadFile/d0e913/lame-question-of-the-day-role-of-curly-braces-in-our-cod/