Java vs. C#
-
#ifdef NO_VECTOR intArray[i] = static_cast<int>(std::numeric_limits<int>::max() * rand() / RAND_MAX + 1.0); doubleArray[i] = (std::numeric_limits<double>::max() * rand() / RAND_MAX + 1.0); #else intArray.push_back(static_cast<int>(std::numeric_limits<int>::max() * std::rand() / RAND_MAX + 1.0)); doubleArray.push_back(std::numeric_limits<double>::max() * std::rand() / RAND_MAX + 1.0); #endif
Stand irgendwo lege ein Feld der Große arrayLength und hänge hinten ein paar Zufalszahlen an? oder was soll das push_back???
Und ich habe grade einfach mahl versucht das ganze auf dem MSVC laufenzulassen. Ging natürlich nicht, weil bei dem nur etwa die hälfte im richtigen Namensraum steht. Und der hat extrem langsame stringstreams. Deshalb habe ich das ganze mal an den MSVC angepast und dann folgende Ergebnisse bekommen
211
434
886
49859
99813
3897nicht grade toll. Ich habe aber grade nur diesen dämlichen Compiler da. *heul*. Könnte mal jemand den Code hier ausprobieren:
#include <iostream> #include <cmath> #include <ctime> #include <fstream> #include <algorithm> #include <functional> #include <limits> #include <sstream> #include <deque> #ifndef NO_VECTOR #include <vector> #endif using namespace std; inline const string to_string(int x) { stringstream tmp; tmp << x; return tmp.str(); } #ifdef WIN32 # include <windows.h> # ifdef _MSC_VER # undef max # endif #else # include <sys/time.h> #endif int main() { #ifdef WIN32 DWORD times[7]; #else struct timeval times[7]; struct timezone tz; #endif const size_t arrayLength=5000000; size_t i=0; //Arrays erzeugen #ifdef WIN32 times[0] = GetTickCount(); #else gettimeofday(×[0], &tz); #endif #ifdef NO_VECTOR int * intArray=new int[arrayLength]; double * doubleArray=new double[arrayLength]; #else vector<int> intArray(arrayLength); vector<double> doubleArray(arrayLength); #endif #ifdef WIN32 times[1] = GetTickCount(); #else gettimeofday(×[1], &tz); #endif cout << "Array erzeugt" << endl; //Zufallszahlen srand( (unsigned int)0 ); for(;i<arrayLength;++i) { intArray[i] = static_cast<int>(std::numeric_limits<int>::max() * rand() / RAND_MAX + 1.0); doubleArray[i] = (std::numeric_limits<double>::max() * rand() / RAND_MAX + 1.0); } #ifdef WIN32 times[2] = GetTickCount(); #else gettimeofday(×[2], &tz); #endif cout << "Zufallszahlen erzeugt" << endl; //Sortieren #ifdef NO_VECTOR sort(&intArray[0], &intArray[arrayLength-1]); #else sort(intArray.begin(), intArray.end()); #endif #ifdef WIN32 times[3] = GetTickCount(); #else gettimeofday(×[3], &tz); #endif cout << "Sortiert" << endl; //int to char deque<string> schlange; ostringstream stringBuffer; for(i=0; i<arrayLength; ++i) { schlange.push_back(to_string(intArray[i])); schlange.push_back("\n"); } #ifdef WIN32 times[4] = GetTickCount(); #else gettimeofday(×[4], &tz); #endif cout << "An String angehaengt" << endl; //string in Datei schreiben ofstream out("demo.txt"); if(!out.is_open()) { std::cerr << "Fehler" << std::endl; #ifdef NO_VECTOR delete[] intArray; delete[] doubleArray; #endif return 1; } for (deque<string>::iterator it = schlange.begin(); it != schlange.end(); ++it) out << *it; out.close(); #ifdef WIN32 times[5] = GetTickCount(); #else gettimeofday(×[5], &tz); #endif cout << "In Datei geschreiben" << endl; //Wurzeln berechnen for(i=0; i<arrayLength; ++i) { doubleArray[i] = sqrt(doubleArray[i]); } #ifdef WIN32 times[6] = GetTickCount(); #else gettimeofday(×[6], &tz); #endif cout << "Wurzeln berechnet" << endl; //Ausgabe: #ifdef WIN32 cout << "Array erzeugen: " << (times[1] - times[0]) << std::endl; cout << "Zufallszahlen erzeugen: " << (times[2] - times[1]) << std::endl; cout << "Sortieren: " << (times[3] - times[2]) << std::endl; cout << "String anhaengen: " << (times[4] - times[3]) << std::endl; cout << "Speichern: " << (times[5] - times[4]) << std::endl; cout << "Wurzeln berechnen: " << (times[6] - times[5]) << std::endl; #else cout << "Array erzeugen: " << (times[1].tv_usec - times[0].tv_usec) << std::endl; cout << "Zufallszahlen erzeugen: " << (times[2].tv_usec - times[1].tv_usec) << std::endl; cout << "Sortieren: " << (times[3].tv_usec - times[2].tv_usec) << std::endl; cout << "String anhaengen: " << (times[4].tv_usec - times[3].tv_usec) << std::endl; cout << "Speichern: " << (times[5].tv_usec - times[4].tv_usec) << std::endl; cout << "Wurzeln berechnen: " << (times[6].tv_usec - times[5].tv_usec) << std::endl; #endif #ifdef NO_VECTOR delete[] intArray; delete[] doubleArray; #endif return 0; }
-
Oh fuck, der schreibt nur einsen in die Datei.
Oh mal sehen
numeric_limits<int>::max() * rand() / RAND_MAX + 1.0 int * int / int + double
die erste multiplikation kann einen überlauf erzeugen. Die division teilt durch eine Zahl, die meist numeric_limits<int>::max() entspricht, also kommt 0 raus und 0 + 1 == 1
ersetzt
numeric_limits<int>::max() * rand() / RAND_MAX + 1.0
durch
static_cast<double>(numeric_limits<int>::max()) * rand() / RAND_MAX + 1.0
dann sollte es gehen
-
Original erstellt von Helium:
**Oh fuck, der schreibt nur einsen in die Datei.
**BAH! ...jetzt muss ich das Programm nochmal testen!
-
Heliums Code mit den genannten Compiler-Optionen :
Es gab noch stärkere Schwankungen, als sonst. Die Ergebnisse können also nur als Anhaltspunkt genommen werden. Die erzeugte Datei scheint mehr oder weniger die richtige Größe zu haben, allerdings enthält sie ungefähr 2,5MB zu viel (vielleicht "\r\n" statt "\n"? ...sollte aber nicht viel ausmachen)
1,2 GHz 1,6 GHz Array : 130 120 Zufallszahlen : 1142 861 sortieren : 1422 1072 String erzeugen : 147612 110609 Speichern : 23464 27679 Wurzel berechnen : 1182 1052
Gerade die Werte beim Speichern und bei den Wurzeln scheinen nicht der tatsächlichen Performance zu entsprechen. Die Größenordnung sollte aber stimmen. ...bei den Wurzeln habe ich (vor den Veränderungen) aber schon Messungen gemacht, die nur etwa die halbe Zeit benötigt hatten.
-
mach am besten 3 Messungen und nimm den Durchschnittswert, da kann sich ja immer etwas ändern, durch swapping etc.
eigentlich wär es am besten in dem Programm den Test 3 mal zu machen, da man dann vom L2 Cache profitieren kann.
-
Ich habe eh mehrmals gemessen und habe dann die schlechtesten Meßergebnisse weggeworfen. Das Problem ist, dass Windows bei mir immer etwas im Hintergrund macht. ...das liegt aber nicht an Programmen, die ich nebenher laufen habe.
Wenn das erste C++-Programm kommt, bei dem kein Schritt länger als 10 Sekunden dauert, mache ich meinetwegen eine Mittelwertbildung über 10 Durchläufe.
...ich denke aber nicht, dass man da vom L2-Cache profitieren kann.
-
hast du zufällig bock dir die SGI-STL-Version runter zu laden. Mich würde mal interessieren, wie die Sich zu der von dir verwendeten verhält. Bei der Dinkumware scheinen deques etwas effektiver zu sein, als bei deiner (Siehe mein MSVC ergebnis. Warum haben wir in der Schule eigentlich nur diesen scheiß-Compiler?)
Das andere ergebnis beim in die Dateischreiben liegt wohl daran, dass meine Dateigröße stimmt.
Das mit den wurzeln ist möglicherweise unfair. Je größe die Zahl, desto länger dauert es die Wurzel zu berechnen. Und bei mir kamen meistens sehr große Zahlen raus.
-
Bei Java werden nur double-Zahlen zwischen 0 und 1 erzeugt. ...kannst du ja bei dir anpassen.
Sag mal, wo man sich die SGI-STL-Version runterladen kann. Vielleicht mache ich das. ...ansonsten kannst du ja auch MinGW runterladen und dann mal berichten, ob es da starke Unterschiede gibt. ...aber egal, ob das etwas besser implementiert ist : Das wird nicht einen Faktor 10 und höher ausmachen.
[ Dieser Beitrag wurde am 12.10.2002 um 20:34 Uhr von Gregor editiert. ]
-
-