C# vb.net速度慢吗?

C# vb.net速度慢吗?,c#,vb.net,algorithm,C#,Vb.net,Algorithm,我用Vb.net和C#编写了相同的项目,并在下面用Visual Studio 2015编写。 Visual Basic项目: Private子按钮1\u单击(发送者作为对象,e作为事件参数)处理按钮1。单击 尺寸j为Int32=0 ' 双精度尺寸偏移=0D'偏移 双倍变暗增益=1D'增益 Dim Freq为双精度=1D'频率 尺寸M为Int32=3000'块数 尺寸N为Int32=每个数据块的30000'数据数量 双精度尺寸增量=0'采样率 Dim DATACUNT As Int32=N*M'总

我用Vb.net和C#编写了相同的项目,并在下面用Visual Studio 2015编写。 Visual Basic项目:

Private子按钮1\u单击(发送者作为对象,e作为事件参数)处理按钮1。单击
尺寸j为Int32=0
'
双精度尺寸偏移=0D'偏移
双倍变暗增益=1D'增益
Dim Freq为双精度=1D'频率
尺寸M为Int32=3000'块数
尺寸N为Int32=每个数据块的30000'数据数量
双精度尺寸增量=0'采样率
Dim DATACUNT As Int32=N*M'总数据计数
'
将X调为双精度
双色
'
delta=N/数据计数
'
“方克西翁
'
像秒表一样暗的时间
时间=新秒表
开始时间()
'
对于b,Int32=0到M-1
对于i作为Int32=0到N-1
X=j*delta
Y=偏移量+增益*Math.Cos(X*Freq*Math.PI/180.0)
j=j+1
下一个
下一个b
'
时间,停止
WriteLine(“运行时间:{0}”,time.appeased)
端接头
和C#项目:

private void按钮1\u单击(对象发送者,事件参数e)
{
int32j=0;
双偏移量=0D;//偏移量
双增益=1D;//增益
双频=1D;//频率
Int32 M=3000;//块数
Int32 N=30000;//每个块的数据数
双增量=0;//采样率
Int32 DataCount=N*M;//总数据计数
//
双X;
双Y;
//
delta=N/数据计数;
//
//方克西翁
//
秒表时间;
时间=新秒表();
Time.Start();
//
对于(Int32 b=0;b
项目运行了三次,获得了延迟时间

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

Elapsed time :00:00:03.9066617
Elapsed time :00:00:03.9165436
Elapsed time :00:00:03.9031542
Elapsed time :00:00:02.4870551
Elapsed time :00:00:02.4931171
Elapsed time :00:00:02.5005793
以及C#项目运行时获得的结果

Elapsed time :00:00:03.9066617
Elapsed time :00:00:03.9165436
Elapsed time :00:00:03.9031542
Elapsed time :00:00:02.4870551
Elapsed time :00:00:02.4931171
Elapsed time :00:00:02.5005793
不同的结果在同一个框架中。vb.net和C#之间的区别不止一秒


为什么vb.net这么慢?

请检查生成的IL代码,查看
C
vb.net
。在我的本地机器中,我观察到它们大致相同,但并不相同。例如,在VB.Net的情况下,它对算术加法、减法等有额外的检查。
VB.Net
使用操作码,如
sub.ovf
mul.ovf
,而C不使用。我为这两种情况提供IL输出。它们是使用发布模式编译的。您可以看到,它们甚至开始与局部变量的数量不同。VB有13个局部变量,其中C#11个局部变量

C#

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

请检查生成的IL代码是否为
C
VB.Net
。在我的本地机器中,我观察到它们大致相同,但并不相同。例如,在VB.Net的情况下,它对算术加法、减法等有额外的检查。
VB.Net
使用操作码,如
sub.ovf
mul.ovf
,而C不使用。我为这两种情况提供IL输出。它们是使用发布模式编译的。您可以看到,它们甚至开始与局部变量的数量不同。VB有13个局部变量,其中C#11个局部变量

C#

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

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

delta = N / DataCount
在VB中,这是算术除法。在C#中,它是整数除法。
在VB中返回
0.00033333…
,在C中返回0

如果将VB代码修复为也使用整数除法:

delta = N \ DataCount

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

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

delta = N / DataCount
在VB中,这是算术除法。在C#中,它是整数除法。
在VB中返回
0.00033333…
,在C中返回0

如果将VB代码修复为也使用整数除法:

delta = N \ DataCount

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

您在发行版中测试过这一点吗?您是否使用了值得尊敬的基准点工具?您是否尝试重置您的电脑并以相反的顺序运行这些程序。我的意思是先是C#one,然后是VB.NET。测量性能并不像在一个环路上启动两个秒表那么简单。顺便问一下,您是否在发布模式下设置了这两个代码?如果您想知道是否存在差异,请检查生成的IL中的两个代码段。顺便说一句,您只需要一行代码就可以创建和启动
秒表
,即
Dim time=Stopwatch.StartNew()
。请尝试在vb项目的高级编译选项中启用未选中的算术。生成的IL使用执行溢出检查的
.ovf
操作码。也可以将vb中的除法从
/
切换到
\
,后者执行整数除法,修改c,使其不是整数除法(将一侧转换为双精度),或者使用至少在整数/浮点除法中表现相同的值。在发布模式下编译,在VisualStudio外部运行,执行三个以上的测试(预热jit并删除一堆测试),并使用适当的基准框架谢谢您的评论。正如Pinkfloydx33所提到的,拆分过程存在问题。您是否在发行版中对此进行了测试,是否使用了值得尊敬的基准点工具?是否尝试重置您的电脑并以相反的顺序运行这些程序。我的意思是先是C#one,然后是VB.NET。测量性能并不像在一个环路上启动两个秒表那么简单。顺便问一下,您是否在发布模式下设置了这两个代码?如果您想知道是否存在差异,请检查生成的IL中的两个代码段。顺便说一下,您只需要一行代码就可以创建和启动秒表