背景
今天早上在运行基准测试时,我和同事们发现了一些关于C#代码与VB.NET代码性能的奇怪现象。
我们开始比较 C# 和 Delphi Prism 计算质数,结果发现 Prism 大约快30%。我想 CodeGear 在生成 IL 时优化了代码(exe
文件大小是 C# 的两倍,并且有各种不同的 IL)。
我决定在 VB.NET 中写一个测试,假设微软的编译器会为每种语言编写基本相同的 IL。然而,结果更加令人震惊:使用相同操作,在 C# 上的代码运行速度是 VB.NET 的三倍慢!
生成的 IL 稍有不同,但并不是非常明显,我也没有能力阅读它以理解差异。
基准测试
下面分别附上每个代码的内容。在我的计算机上,VB 在大约6.36秒内找到了 348513 个质数。C# 则需要 21.76 秒才能找到同样数量的质数。
计算机规格和注意事项
- Intel Core 2 Quad 6600 @ 2.4Ghz
在我测试的每台计算机上,C# 和 VB.NET 之间的基准测试结果都有明显差异。
这两个控制台应用程序都是在发布模式下编译的,但除此之外,没有对Visual Studio 2008生成的默认项目设置进行更改。
VB.NET 代码
Imports System.Diagnostics
Module Module1
Private temp As List(Of Int32)
Private sw As Stopwatch
Private totalSeconds As Double
Sub Main()
serialCalc()
End Sub
Private Sub serialCalc()
temp = New List(Of Int32)()
sw = Stopwatch.StartNew()
For i As Int32 = 2 To 5000000
testIfPrimeSerial(i)
Next
sw.Stop()
totalSeconds = sw.Elapsed.TotalSeconds
Console.WriteLine(String.Format("{0} seconds elapsed.", totalSeconds))
Console.WriteLine(String.Format("{0} primes found.", temp.Count))
Console.ReadKey()
End Sub
Private Sub testIfPrimeSerial(ByVal suspectPrime As Int32)
For i As Int32 = 2 To Math.Sqrt(suspectPrime)
If (suspectPrime Mod i = 0) Then
Exit Sub
End If
Next
temp.Add(suspectPrime)
End Sub
End Module
C# 代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace FindPrimesCSharp {
class Program {
List<Int32> temp = new List<Int32>();
Stopwatch sw;
double totalSeconds;
static void Main(string[] args) {
new Program().serialCalc();
}
private void serialCalc() {
temp = new List<Int32>();
sw = Stopwatch.StartNew();
for (Int32 i = 2; i <= 5000000; i++) {
testIfPrimeSerial(i);
}
sw.Stop();
totalSeconds = sw.Elapsed.TotalSeconds;
Console.WriteLine(string.Format("{0} seconds elapsed.", totalSeconds));
Console.WriteLine(string.Format("{0} primes found.", temp.Count));
Console.ReadKey();
}
private void testIfPrimeSerial(Int32 suspectPrime) {
for (Int32 i = 2; i <= Math.Sqrt(suspectPrime); i++) {
if (suspectPrime % i == 0)
return;
}
temp.Add(suspectPrime);
}
}
}
C#中执行Math.Sqrt()
为什么比VB.NET慢?
l_
在那里做了什么。 - MarkJ