Neden yok C# Matematik yürütmek.() Karekök VB.NET daha mı yavaş
Arka plan
Kıyaslama testleri bu sabah koşarken ben ve arkadaşlarım, bazı garip şeyler performansına ilişkin keşfedilen C# kodu vs VB.NET kod.
C karşılaştırarak başladık# Delphi vs asal sayı hesaplama Prizma ve Prizma 0 daha hızlı olduğunu buldu. IL oluştururken CodeGear optimize kod daha buldum (exe
C yaklaşık iki katı kadar büyüktü#'s ve farklı IL yaşamaktaydı.)
VB.NET bir test gibi bir şey yazmak için Microsoft'un derleyicileri her dil için temelde aynı IL yazma sona ereceğini varsayarak karar verdim. Ancak, sonuç daha da şok ediciydi:aynı işlemi VB. kodu C üzerinde üç kat daha yavaş çalışırdı#
Oluşturulan IL farklıydı, ama çok çok, ve bu farklılıkları anlamak için okuma konusunda yeterince iyi değilim.
Kriterler
Her biri için aşağıdaki kodu ekledim. Benim makinede, VB hakkında 348513 asal sayıları bulur6.36saniye. C# asal sayılar aynı sayıda yer bulur21.76saniye.
Bilgisayar Özellikleri ve Notlar
- Intel Core 2 Quad 6600 @ 2.4 Ghz
Orada test ettim her makine C arasında kıyaslama sonuçları gözle görülür bir fark var# VB.NET.
Hem konsol uygulamaları Serbest modunda derlenmiştir, ama bunun dışında hiç bir proje ayarlarını varsayılan olarak, Visual Studio 2008 tarafından üretilen değiştirildi.
VB.NET kod
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# Kodu
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);
}
}
}
Neden C#'Math.Sqrt()
s yürütme VB.NET daha yavaş?
CEVAP
C# uygulama VB sadece döngünün başında hesaplar iken döngü Math.Sqrt(suspectPrime)
her zaman yeniden hesaplama. Bu sadece kontrol yapısının doğası nedeniyle. C#, for
VB ayrı inşa ederken while
sadece bir fantezi döngü.
Bu döngü kullanarak skor bile
Int32 sqrt = (int)Math.Sqrt(suspectPrime)
for (Int32 i = 2; i <= sqrt; i ) {
if (suspectPrime % i == 0)
return;
}
Neden SSE x * Karekök(x) rsqrt daha ya...
Neden bir döngü iki döngü daha yavaş g...
Neden bazı yüzer < karşılaştırmalar...
Neden sıralanmış bir dizi sıralanmamış...
Neden 512x512 matrix 513x513 bir matri...