带循环和类型C#的高效代码

guy*_*uyl 0 .net c# optimization foreach micro-optimization


我想在下面的代码值类型中找出更有效(如果是甚至)的内容

ForEach(string s in strings)
{
  string t = s;
}
// or
string t;
ForEach(string s in strings)
{
   t = s;
}
Run Code Online (Sandbox Code Playgroud)

和引用类型有什么不同.

Cod*_*ray 10

这两个代码片段产生完全相同的IL.这是我用来测试的C#代码:

  public string[] strings = new string[5];

  public void TestOne()
  {
     foreach (string s in strings)
     {
        string t = s;
     }
  }

  public void TestTwo()
  {
     string t;
     foreach (string s in strings)
     {
        t = s;
     }
  }
Run Code Online (Sandbox Code Playgroud)

这是在启用优化后编译的两种方法的结果IL:

.method public hidebysig instance void  TestOne() cil managed
{
  // Code size       26 (0x1a)
  .maxstack  2
  .locals init ([0] string s,
           [1] string[] CS$6$0000,
           [2] int32 CS$7$0001)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      string[] strings
  IL_0006:  stloc.1
  IL_0007:  ldc.i4.0
  IL_0008:  stloc.2
  IL_0009:  br.s       IL_0013
  IL_000b:  ldloc.1
  IL_000c:  ldloc.2
  IL_000d:  ldelem.ref
  IL_000e:  stloc.0
  IL_000f:  ldloc.2
  IL_0010:  ldc.i4.1
  IL_0011:  add
  IL_0012:  stloc.2
  IL_0013:  ldloc.2
  IL_0014:  ldloc.1
  IL_0015:  ldlen
  IL_0016:  conv.i4
  IL_0017:  blt.s      IL_000b
  IL_0019:  ret
} // end of method TestOne


.method public hidebysig instance void  TestTwo() cil managed
{
  // Code size       26 (0x1a)
  .maxstack  2
  .locals init ([0] string s,
           [1] string[] CS$6$0000,
           [2] int32 CS$7$0001)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      string[] strings
  IL_0006:  stloc.1
  IL_0007:  ldc.i4.0
  IL_0008:  stloc.2
  IL_0009:  br.s       IL_0013
  IL_000b:  ldloc.1
  IL_000c:  ldloc.2
  IL_000d:  ldelem.ref
  IL_000e:  stloc.0
  IL_000f:  ldloc.2
  IL_0010:  ldc.i4.1
  IL_0011:  add
  IL_0012:  stloc.2
  IL_0013:  ldloc.2
  IL_0014:  ldloc.1
  IL_0015:  ldlen
  IL_0016:  conv.i4
  IL_0017:  blt.s      IL_000b
  IL_0019:  ret
} // end of method TestTwo
Run Code Online (Sandbox Code Playgroud)

像往常一样,规则是相同的:信任你的编译器.让它为您处理这些优化,而不是在编写代码时试图担心它.只需编写有意义且可读的代码即可.

最重要的是,忽略所有认为其中一个在理论上比另一个更好的人.这纯属无稽之谈.在编译代码之前,没有相关的理论是相关的.而且由于它编译成完全相同的东西,它保证在性能上完全相同.

但如果你仍然不相信我的信任你的编译器(我们中的一些人很顽固,我知道,因为即使我有时仍然),至少你现在知道如何自己回答这些类型的问题.编写一些演示两种变体的示例代码,在"Release"模式下编译,然后在ILDASM.exe中打开程序集并自行比较生成的IL代码.这样的事情很容易测试,没有理由猜测.


Jus*_*tin 5

那么这些都不会编译(我想你想用foreach而不是ForEach?),但如果他们这样做,他们应该在优化后编译到同一个IL,所以没有区别.