【发布时间】:2011-03-02 20:14:05
【问题描述】:
背景
今天早上运行基准测试时,我和我的同事发现了一些关于 C# 代码与 VB.NET 代码性能的奇怪事情。
我们开始比较 C# 与 Delphi Prism 计算素数,发现 Prism 快了大约 30%。我认为 CodeGear 在生成 IL 时对代码进行了更多优化(exe 大约是 C# 的两倍,并且其中包含各种不同的 IL。)
我决定也用 VB.NET 编写一个测试,假设微软的编译器最终会为每种语言编写基本相同的 IL。然而,结果更令人震惊:在 C# 上运行相同操作的代码比 VB 慢三倍以上!
生成的 IL 是不同的,但不是非常不同,而且我还不够擅长阅读它来理解差异。
基准测试
我已经包含了下面每个的代码。在我的机器上,VB 在大约 6.36 秒内找到了 348513 个素数。 C# 在 21.76 秒内找到相同数量的素数。
计算机规格和说明
- 英特尔酷睿 2 四核 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 慢?
【问题讨论】:
-
这两个代码示例在一个小点上有很大的不同,导致这个基准完全错误。
-
@I__:我知道你在那里做了什么。
-
@matt 我不看到
l_在那里做了什么。 -
这个确切的问题(VB.Net 的 For...To 循环的评估一次行为)最近在这里出现:stackoverflow.com/q/52607611
标签: c# .net vb.net benchmarking