Why does C# execute Math.Sqrt() more slowly than VB.NET?

后端 未结 6 1565
情深已故
情深已故 2020-12-14 05:45

Background

While running benchmark tests this morning, my colleagues and I discovered some strange things concerning performance of C# code vs. VB.NET code.

6条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-14 06:14

    Here is the decompiled IL from the for loops. If you compare the two you will see VB.Net only does the Math.Sqrt(...) onces while C# checks it on each pass. To fix this you would need to do something like var sqrt = (int)Math.Sqrt(suspectPrime); as other have suggested.

    ... VB ...

    .method private static void CheckPrime(int32 suspectPrime) cil managed
    {
        // Code size       34 (0x22)
        .maxstack  2
        .locals init ([0] int32 i,
             [1] int32 VB$t_i4$L0)
        IL_0000:  ldc.i4.2
        IL_0001:  ldarg.0
        IL_0002:  conv.r8
        IL_0003:  call       float64 [mscorlib]System.Math::Sqrt(float64)
        IL_0008:  call       float64 [mscorlib]System.Math::Round(float64)
        IL_000d:  conv.ovf.i4
        IL_000e:  stloc.1
        IL_000f:  stloc.0
        IL_0010:  br.s       IL_001d
    
        IL_0012:  ldarg.0
        IL_0013:  ldloc.0
        IL_0014:  rem
        IL_0015:  ldc.i4.0
        IL_0016:  bne.un.s   IL_0019
    
        IL_0018:  ret
    
        IL_0019:  ldloc.0
        IL_001a:  ldc.i4.1
        IL_001b:  add.ovf
        IL_001c:  stloc.0
        IL_001d:  ldloc.0
        IL_001e:  ldloc.1
        IL_001f:  ble.s      IL_0012
    
        IL_0021:  ret
    } // end of method Module1::testIfPrimeSerial
    

    ... C# ...

    .method private hidebysig static void CheckPrime(int32 suspectPrime) cil managed
    {
        // Code size       26 (0x1a)
        .maxstack  2
        .locals init ([0] int32 i)
        IL_0000:  ldc.i4.2
        IL_0001:  stloc.0
        IL_0002:  br.s       IL_000e
    
        IL_0004:  ldarg.0
        IL_0005:  ldloc.0
        IL_0006:  rem
        IL_0007:  brtrue.s   IL_000a
    
        IL_0009:  ret
    
        IL_000a:  ldloc.0
        IL_000b:  ldc.i4.1
        IL_000c:  add
        IL_000d:  stloc.0
        IL_000e:  ldloc.0
        IL_000f:  conv.r8
        IL_0010:  ldarg.0
        IL_0011:  conv.r8
        IL_0012:  call       float64 [mscorlib]System.Math::Sqrt(float64)
        IL_0017:  ble.s      IL_0004
    
        IL_0019:  ret
    } // end of method Program::testIfPrimeSerial
    

提交回复
热议问题