vb.net慢吗?

时间:2018-12-26 09:11:33

标签: c# vb.net algorithm

我在下面的Visual Studio 2015中准备了用Vb.net和C#编写的同一项目。 Visual Basic项目:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim j As Int32 = 0
    '
    Dim Offset As Double = 0D   ' Offset
    Dim Gain As Double = 1D     ' Gain
    Dim Freq As Double = 1D     ' Frequency
    Dim M As Int32 = 3000    ' Number of Block
    Dim N As Int32 = 30000    ' Number of data each block
    Dim delta As Double = 0     ' Sample rate
    Dim DataCount As Int32 = N * M  ' Total data count   
    '
    Dim X As Double
    Dim Y As Double
    '
    delta = N / DataCount
    '
    ' Fonksiyon
    '
    Dim Time As Stopwatch
    Time = New Stopwatch
    Time.Start()
    '
    For b As Int32 = 0 To M - 1
        For i As Int32 = 0 To N - 1
            X = j * delta
            Y = Offset + Gain * Math.Cos(X * Freq * Math.PI / 180.0)
            j = j + 1
        Next
    Next b
    '
    Time.Stop()
    Console.WriteLine("Elapsed time :{0}", Time.Elapsed)
End Sub

和C#项目:

 private void button1_Click(object sender, EventArgs e)
    {

        Int32 j = 0;

        Double Offset = 0D;  // Offset
        Double Gain = 1D;     // Gain
        Double Freq = 1D;     // Frequency
        Int32 M = 3000;    // Number of Block
        Int32 N = 30000;    // Number of data each block
        Double delta = 0;     // Sample rate
        Int32 DataCount = N * M;  // Total data count   
        //
        Double X;
        Double Y;
        //
        delta = N / DataCount;
        //
        // Fonksiyon
        //
        Stopwatch Time;
        Time = new Stopwatch();
        Time.Start();
        //
        for (Int32 b=0; b< M; b++) {

            for (Int32 i= 0; i < N; i++) {
            X = j * delta;
            Y = Offset + Gain * Math.Cos(X * Freq * Math.PI / 180.0);
            j = j + 1;
            }
        }
        //
        Time.Stop();
        Console.WriteLine("Elapsed time :{0}", Time.Elapsed);
    }

项目运行了3次,并获得了延迟时间。

运行Visual Basic项目时获得的结果;

Elapsed time :00:00:03.9066617
Elapsed time :00:00:03.9165436
Elapsed time :00:00:03.9031542

运行C#项目时获得的结果;

Elapsed time :00:00:02.4870551
Elapsed time :00:00:02.4931171
Elapsed time :00:00:02.5005793

在相同框架中的不同结果。 vb.net和C#之间的区别超过第二个。

为什么vb.net这么慢?

2 个答案:

答案 0 :(得分:3)

这两个代码在这一行中有重要区别:

delta = N / DataCount

在VB中,这是算术除法。在C#中,它是整数除法。
在VB中返回0.00033333...,在C#中返回0。

如果您将VB代码固定为也使用整数除法:

delta = N \ DataCount

这两个代码开始显示完全相同的时间。

答案 1 :(得分:0)

请检查为C#VB.Net生成的IL代码。在我的本地计算机上,我观察到它们大致相等,但不相同。例如,对于VB.Net,它对算术加法,减法等进行了额外的检查。VB.NET使用诸如sub.ovfmul.ovf之类的操作码,而C#则没有。我提供两种情况的IL输出。它们使用发布模式进行编译。您可以看到它们甚至开始不同于局部变量的数量。 VB有13个本地人,而C#为11个本地人。

C#

 .method /*06000002*/ private hidebysig instance void 
    button1_Click(
      /*08000001*/ object sender, 
      /*08000002*/ class [mscorlib/*23000001*/]System.EventArgs/*01000014*/ e
    ) cil managed 
  {
    .maxstack 2
    .locals /*11000002*/ init (
      [0] int32 j,
      [1] float64 Offset,
      [2] float64 Gain,
      [3] float64 Freq,
      [4] int32 M,
      [5] int32 N,
      [6] float64 delta,
      [7] int32 DataCount,
      [8] float64 X,
      [9] class [System/*23000003*/]System.Diagnostics.Stopwatch/*01000015*/ Time,
      [10] int32 b,
      [11] int32 i
    )

    // [38 13 - 38 25]
    IL_0000: ldc.i4.0     
    IL_0001: stloc.0      // j

    // [40 13 - 40 32]
    IL_0002: ldc.r8       0.0
    IL_000b: stloc.1      // Offset

    // [41 13 - 41 30]
    IL_000c: ldc.r8       1
    IL_0015: stloc.2      // Gain

    // [42 13 - 42 30]
    IL_0016: ldc.r8       1
    IL_001f: stloc.3      // Freq

    // [43 13 - 43 28]
    IL_0020: ldc.i4       3000 // 0x00000bb8
    IL_0025: stloc.s      M

    // [44 13 - 44 29]
    IL_0027: ldc.i4       30000 // 0x00007530
    IL_002c: stloc.s      N

    // [45 13 - 45 30]
    IL_002e: ldc.r8       0.0
    IL_0037: stloc.s      delta

    // [46 13 - 46 37]
    IL_0039: ldloc.s      N
    IL_003b: ldloc.s      M
    IL_003d: mul          
    IL_003e: stloc.s      DataCount

    // [51 13 - 51 35]
    IL_0040: ldloc.s      N
    IL_0042: ldloc.s      DataCount
    IL_0044: div          
    IL_0045: conv.r8      
    IL_0046: stloc.s      delta

    // [56 13 - 56 36]
    IL_0048: newobj       instance void [System/*23000003*/]System.Diagnostics.Stopwatch/*01000015*/::.ctor()/*0A00001D*/
    IL_004d: stloc.s      Time

    // [57 13 - 57 26]
    IL_004f: ldloc.s      Time
    IL_0051: callvirt     instance void [System/*23000003*/]System.Diagnostics.Stopwatch/*01000015*/::Start()/*0A00001E*/

    // [59 18 - 59 29]
    IL_0056: ldc.i4.0     
    IL_0057: stloc.s      b

    IL_0059: br.s         IL_009b
    // start of loop, entry point: IL_009b

      // [62 22 - 62 33]
      IL_005b: ldc.i4.0     
      IL_005c: stloc.s      i

      IL_005e: br.s         IL_008f
      // start of loop, entry point: IL_008f

        // [64 21 - 64 35]
        IL_0060: ldloc.0      // j
        IL_0061: conv.r8      
        IL_0062: ldloc.s      delta
        IL_0064: mul          
        IL_0065: stloc.s      X

        // [65 21 - 65 78]
        IL_0067: ldloc.s      X
        IL_0069: ldloc.3      // Freq
        IL_006a: mul          
        IL_006b: ldc.r8       3.14159265358979
        IL_0074: mul          
        IL_0075: ldc.r8       180
        IL_007e: div          
        IL_007f: call         float64 [mscorlib/*23000001*/]System.Math/*01000024*/::Cos(float64)/*0A00001F*/
        IL_0084: pop          

        // [66 21 - 66 31]
        IL_0085: ldloc.0      // j
        IL_0086: ldc.i4.1     
        IL_0087: add          
        IL_0088: stloc.0      // j

        // [62 42 - 62 45]
        IL_0089: ldloc.s      i
        IL_008b: ldc.i4.1     
        IL_008c: add          
        IL_008d: stloc.s      i

        // [62 35 - 62 40]
        IL_008f: ldloc.s      i
        IL_0091: ldloc.s      N
        IL_0093: blt.s        IL_0060
      // end of loop

      // [59 38 - 59 41]
      IL_0095: ldloc.s      b
      IL_0097: ldc.i4.1     
      IL_0098: add          
      IL_0099: stloc.s      b

      // [59 31 - 59 36]
      IL_009b: ldloc.s      b
      IL_009d: ldloc.s      M
      IL_009f: blt.s        IL_005b
    // end of loop

    // [70 13 - 70 25]
    IL_00a1: ldloc.s      Time
    IL_00a3: callvirt     instance void [System/*23000003*/]System.Diagnostics.Stopwatch/*01000015*/::Stop()/*0A000020*/

    // [71 13 - 71 66]
    IL_00a8: ldstr        "Elapsed time :{0}"
    IL_00ad: ldloc.s      Time
    IL_00af: callvirt     instance valuetype [mscorlib/*23000001*/]System.TimeSpan/*01000025*/ [System/*23000003*/]System.Diagnostics.Stopwatch/*01000015*/::get_Elapsed()/*0A000021*/
    IL_00b4: box          [mscorlib/*23000001*/]System.TimeSpan/*01000025*/
    IL_00b9: call         void [mscorlib/*23000001*/]System.Console/*01000026*/::WriteLine(string, object)/*0A000022*/

    // [72 9 - 72 10]
    IL_00be: ret          

  } // end of method Form1::button1_Click

VB.NET

    .method /*06000014*/ private instance void 
        Button1_Click(
          /*08000005*/ object sender, 
          /*08000006*/ class [mscorlib/*23000001*/]System.EventArgs/*01000027*/ e
        ) cil managed 
      {
        .maxstack 2
        .locals /*11000002*/ init (
          [0] int32 j,
          [1] float64 Offset,
          [2] float64 Gain,
          [3] float64 Freq,
          [4] int32 M,
          [5] int32 N,
          [6] float64 delta,
          [7] int32 DataCount,
          [8] float64 X,
          [9] class [System/*23000002*/]System.Diagnostics.Stopwatch/*0100002C*/ Time,
          [10] int32 V_10,
          [11] int32 b,
          [12] int32 V_12,
          [13] int32 i
        )

        // [3 13 - 3 27]
        IL_0000: ldc.i4.0     
        IL_0001: stloc.0      // j

        // [5 13 - 5 34]
        IL_0002: ldc.r8       0.0
        IL_000b: stloc.1      // Offset

        // [6 13 - 6 32]
        IL_000c: ldc.r8       1
        IL_0015: stloc.2      // Gain

        // [7 13 - 7 32]
        IL_0016: ldc.r8       1
        IL_001f: stloc.3      // Freq

        // [8 13 - 8 30]
        IL_0020: ldc.i4       3000 // 0x00000bb8
        IL_0025: stloc.s      M

        // [9 13 - 9 31]
        IL_0027: ldc.i4       30000 // 0x00007530
        IL_002c: stloc.s      N

        // [10 13 - 10 32]
        IL_002e: ldc.r8       0.0
        IL_0037: stloc.s      delta

        // [11 13 - 11 39]
        IL_0039: ldloc.s      N
        IL_003b: ldloc.s      M
        IL_003d: mul.ovf      
        IL_003e: stloc.s      DataCount

        // [17 9 - 17 30]
        IL_0040: ldloc.s      N
        IL_0042: conv.r8      
        IL_0043: ldloc.s      DataCount
        IL_0045: conv.r8      
        IL_0046: div          
        IL_0047: stloc.s      delta

        // [22 9 - 22 29]
        IL_0049: newobj       instance void [System/*23000002*/]System.Diagnostics.Stopwatch/*0100002C*/::.ctor()/*0A000040*/
        IL_004e: stloc.s      Time

        // [23 9 - 23 21]
        IL_0050: ldloc.s      Time
        IL_0052: callvirt     instance void [System/*23000002*/]System.Diagnostics.Stopwatch/*0100002C*/::Start()/*0A000041*/

        // [25 9 - 25 36]
        IL_0057: ldloc.s      M
        IL_0059: ldc.i4.1     
        IL_005a: sub.ovf      
        IL_005b: stloc.s      V_10
        IL_005d: ldc.i4.0     
        IL_005e: stloc.s      b

        IL_0060: br.s         IL_00a8
        // start of loop, entry point: IL_00a8

          // [26 13 - 26 40]
          IL_0062: ldloc.s      N
          IL_0064: ldc.i4.1     
          IL_0065: sub.ovf      
          IL_0066: stloc.s      V_12
          IL_0068: ldc.i4.0     
          IL_0069: stloc.s      i

          IL_006b: br.s         IL_009c
          // start of loop, entry point: IL_009c

            // [27 17 - 27 30]
            IL_006d: ldloc.0      // j
            IL_006e: conv.r8      
            IL_006f: ldloc.s      delta
            IL_0071: mul          
            IL_0072: stloc.s      X

            // [28 17 - 28 73]
            IL_0074: ldloc.s      X
            IL_0076: ldloc.3      // Freq
            IL_0077: mul          
            IL_0078: ldc.r8       3.14159265358979
            IL_0081: mul          
            IL_0082: ldc.r8       180
            IL_008b: div          
            IL_008c: call         float64 [mscorlib/*23000001*/]System.Math/*01000038*/::Cos(float64)/*0A000042*/
            IL_0091: pop          

            // [29 17 - 29 26]
            IL_0092: ldloc.0      // j
            IL_0093: ldc.i4.1     
            IL_0094: add.ovf      
            IL_0095: stloc.0      // j

            // [30 13 - 30 17]
            IL_0096: ldloc.s      i
            IL_0098: ldc.i4.1     
            IL_0099: add.ovf      
            IL_009a: stloc.s      i

            IL_009c: ldloc.s      i
            IL_009e: ldloc.s      V_12
            IL_00a0: ble.s        IL_006d
          // end of loop

          // [31 9 - 31 15]
          IL_00a2: ldloc.s      b
          IL_00a4: ldc.i4.1     
          IL_00a5: add.ovf      
          IL_00a6: stloc.s      b

          IL_00a8: ldloc.s      b
          IL_00aa: ldloc.s      V_10
          IL_00ac: ble.s        IL_0062
        // end of loop

        // [33 9 - 33 20]
        IL_00ae: ldloc.s      Time
        IL_00b0: callvirt     instance void [System/*23000002*/]System.Diagnostics.Stopwatch/*0100002C*/::Stop()/*0A000043*/

        // [34 9 - 34 61]
        IL_00b5: ldstr        "Elapsed time :{0}"
        IL_00ba: ldloc.s      Time
        IL_00bc: callvirt     instance valuetype [mscorlib/*23000001*/]System.TimeSpan/*01000039*/ [System/*23000002*/]System.Diagnostics.Stopwatch/*0100002C*/::get_Elapsed()/*0A000044*/
        IL_00c1: box          [mscorlib/*23000001*/]System.TimeSpan/*01000039*/
        IL_00c6: call         void [mscorlib/*23000001*/]System.Console/*0100003A*/::WriteLine(string, object)/*0A000045*/

        // [35 5 - 35 12]
        IL_00cb: ret          

      } // end of method Form1::Button1_Click