In letzter Zeit hab ich immer mal wieder ein Auge auf C++ geworfen und möchte auch in Zukunft meine Kenntnisse dorthin erweitern.
Bisher habe ich hauptsächlich C# und Java programmiert.
Eines Abends war mir langweilig und ich habe ein wenig mit C# und C++ gespielt und ein wenig die Performance verglichen, soweit es mir möglich war.
Die Idee hinter dem Test war eigentlich nur, möglichst viele möglichst kleine Packete in Form von structs zu verarbeiten.
Dazu habe ich mir zwei sehr einfache structs in C# und C++ geschrieben.
Hierbei ging es mir nur darum, ein sehr kleines Packet zu erzeugen.
Nun habe ich zwei for-Schleifen genommen, die äußere für die Anzahl der Runden und die innere für die Iterationen pro Runde.
Mir ist bekannt, dass es oft nicht sinnvoll ist, Code 1:1 von einer Sprache in die andere zu konvertieren, da andere Sprache anders arbeiten. Aber bei diesem Test habe ich es mal gemacht.
Ich habe den Test nun durchlaufen lassen mit 10 Runden und 10.000.000 Iterationen pro Runde.
Erwartet habe ich eigentlich, dass C++ zumindestens ein wenig schneller ist als C#, ich wurde allerdings eines besseren belehrt.
Pro Runde hat die C++ Version ca. 120ms und die C# Version ca. 100ms gebraucht. Auf jedenfall war die C# Version bisher immer schneller.
Es ist ewig her, dass ich mit C++ gearbeitet habe und wollte nun mal nachfragen, wo der Grund dafür liegt.
Ist der Test einfach nur schlecht bzw nicht geeignet, ist der C++ Code/C# Code nicht optimal oder gibt es irgendeinen anderen Grund?
Oder ist C# in diesem Szenario einfach C++ überlegen?
Update1:
Nachdem ich mich nach möglichen Performanceverbesserungen umgeschaut habe, kam ich zum Thema RNG (random number generation) und einen interessanten Beitrag von Intel ([Only registered and activated users can see links. Click Here To Register...]
Dies dort beschriebene Methode soll den Standardgenerator ablösen und wesentlich schneller sein.
Also hab ich mir den Code kopiert und diese Methode verwendet (sowohl bei C++ als auch C#, wobei die C# Version etwas umgeschrieben werden musste).
Das hat zumindestens den ersten Durchbruch gebracht.
Der C++ Code braucht nun nur noch ca. 15ms für eine Runde und der C# Code ganze 50ms.
Jetzt ist der Jagdtrieb erst recht geweckt :D
Mal schauen, was ich noch so finde.
Update2:
Aufgrund von snow's Anmerkung, dass std::cout seines Wissens nach langsam sei, habe ich die Ausgabe dahingehend verändert, dass ich die Rundenergebnisse in ein Array speicher und am Ende ausgeben lasse.
Allerdings hat diese Änderung keinen Einfluss auf die Rundenzeit, da die Ausgabe bereits in der alten Version nicht mehr mitgemessen wurde.
Bisher habe ich hauptsächlich C# und Java programmiert.
Eines Abends war mir langweilig und ich habe ein wenig mit C# und C++ gespielt und ein wenig die Performance verglichen, soweit es mir möglich war.
Die Idee hinter dem Test war eigentlich nur, möglichst viele möglichst kleine Packete in Form von structs zu verarbeiten.
Dazu habe ich mir zwei sehr einfache structs in C# und C++ geschrieben.
Hierbei ging es mir nur darum, ein sehr kleines Packet zu erzeugen.
Code:
//C++
struct Packet
{
int x;
};
//C#
struct Packet
{
public int x;
}
Code:
//C++
using namespace std;
srand(time(NULL));
for (int r = 0; r < rounds; r++)
{
clock_t start = clock();
int hits = 0;
for (int i = 0; i < iterationsPerRound; i++)
{
Packet packet;
packet.x = rand();
if (packet.x == 0)
hits++;
}
clock_t end = clock();
cout << "\nRound #" << (r + 1) << ": " << double((end-start))/CLOCKS_PER_SEC << "s (Hits: " << hits << ")" << endl;
}
//C#
var random = new Random(0xDEAD);
var swatch = new Stopwatch();
for (var r = 0; r < rounds; r++)
{
swatch.Restart();
var hits = 0;
for (var i = 0; i < iterationsPerRound; i++)
{
Packet packet;
packet.x = random.Next();
if (packet.x == 0)
hits++;
}
swatch.Stop();
Console.WriteLine("Round#{0}: {1} s ({2} Hits)", (r + 1), (double)swatch.ElapsedMilliseconds / 1000, hits);
}
Ich habe den Test nun durchlaufen lassen mit 10 Runden und 10.000.000 Iterationen pro Runde.
Erwartet habe ich eigentlich, dass C++ zumindestens ein wenig schneller ist als C#, ich wurde allerdings eines besseren belehrt.
Pro Runde hat die C++ Version ca. 120ms und die C# Version ca. 100ms gebraucht. Auf jedenfall war die C# Version bisher immer schneller.
Es ist ewig her, dass ich mit C++ gearbeitet habe und wollte nun mal nachfragen, wo der Grund dafür liegt.
Ist der Test einfach nur schlecht bzw nicht geeignet, ist der C++ Code/C# Code nicht optimal oder gibt es irgendeinen anderen Grund?
Oder ist C# in diesem Szenario einfach C++ überlegen?
Update1:
Nachdem ich mich nach möglichen Performanceverbesserungen umgeschaut habe, kam ich zum Thema RNG (random number generation) und einen interessanten Beitrag von Intel ([Only registered and activated users can see links. Click Here To Register...]
Dies dort beschriebene Methode soll den Standardgenerator ablösen und wesentlich schneller sein.
Also hab ich mir den Code kopiert und diese Methode verwendet (sowohl bei C++ als auch C#, wobei die C# Version etwas umgeschrieben werden musste).
Das hat zumindestens den ersten Durchbruch gebracht.
Der C++ Code braucht nun nur noch ca. 15ms für eine Runde und der C# Code ganze 50ms.
Jetzt ist der Jagdtrieb erst recht geweckt :D
Mal schauen, was ich noch so finde.
Update2:
Aufgrund von snow's Anmerkung, dass std::cout seines Wissens nach langsam sei, habe ich die Ausgabe dahingehend verändert, dass ich die Rundenergebnisse in ein Array speicher und am Ende ausgeben lasse.
Allerdings hat diese Änderung keinen Einfluss auf die Rundenzeit, da die Ausgabe bereits in der alten Version nicht mehr mitgemessen wurde.