我在下面的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这么慢?
答案 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.ovf
,mul.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