Ausgabe nur im Debug Modus
-
Hallo, ich würde gerne bei verschiedenen Sortieralgorithmen die Zeit messen, doch im Code des Algorithmus selber stehen auch die Ausgaben nach jedem Durchlauf, diese sollen aber bei der Zeitmessung nicht beachtet werden!
Hier ist zum Beispiel der Code für einen Insertionsorttemplate <class T> vector<T> insertionsort(vector<T> v1, int abstand = 1){ int pos; T zwischenspeicher; cout << "Insertion Sort: Ausgabe von Insertion Sort:\n"; //Schleife um das Array zum sortieren zu durchlaufen for(int i = abstand; i < (int) v1.size(); i++){ zwischenspeicher = v1[i]; pos = i-abstand; //Schleife um das aktuell zu sortierende Element an die richtige Position zu setzen while(1){ //Ist das zu sortierende Element kleiner als ein voriges, wird das vorige an die nächste Position geschrieben if(zwischenspeicher < v1[pos]){ v1[pos+abstand] = v1[pos]; //Gibt es kein Element mehr, welches ueberprueft werden kann bzw man ist am Anfang des Vektors //dann ist das zu sortierende Element das kleinste in diesem durchlauf und wird an die stelle gesetzt if(pos < abstand){ v1[pos] = zwischenspeicher; break; } pos-=abstand; } //Ist das zu sortierende Element nicht kleiner als der nächste zu überprüfende Vorgänger //wird es an die nächste Stelle gesetzt und die Schleife verlassen else{ v1[pos+abstand] = zwischenspeicher; break; } } cout << "Durchlauf " << i-abstand+1 << ": "; for(int z=0;z <(int) v1.size();z++){ cout << v1[z] << " "; } cout << endl; } return v1; }Ich rufe diesen mit der Zeitmessung in der main dann wie folgt auf.
clock_t start, end; // Zeitstempel float diff_time; // Differenz der Zeitstempel start = clock(); vector<int> v2 = insertionsort<int>(v1); end = clock(); diff_time = ((float)(end-start)/CLOCKS_PER_SEC);Das Problem ist aber nun, dass die Ausgaben mit in die Zeitrechnung einfließen, was ich aber für eine bestimmte Aufgabenstellung nicht will. Das Problem ist, dass ich nicht weiß wie ich zum Beispiel einfach alle Ausgaben "deaktivieren" kann für einen bestimmten Teil.
#ifdef ??? vector<int> v2 = insertionsort<int>(v1); #endifAm besten wäre es, wenn ich so eine Anweisung in der Main um den Aufruf schreiben kann, das Problem ist nur, dass ich genau an dieser Stelle nicht weiter komme.
http://www.c-plusplus.net/forum/219825Ich habe mir diesen Thread auch schon durchgelesen, aber blicke da ehrlich gesagt nicht ganz durch und hatte die dortige Lösung zum Testen einfach mal kopiert, was mich aber aus mangelndem Verständnis auch nicht weiter gebracht hat.
Falls mir jemand sagen kann was ich dort schreiben muss, wäre ich sehr dankbar
-
Wenn du es halbwegs einfach haben möchtest, dann machst du etwas wie:
debug.h:
#ifdef DEBUG # define DEBUG_OUT(x) cerr << x #else # define DEBUG_OUT(x) do {} while (0) #endifIm Code ersetzt du dann beispielsweise
cout << v1[z] << " ";durch
DEBUG_OUT(v1[z] << " ");Dann übersetzt du den Code im Debugmodus mit dem Symbol DEBUG gesetzt und ansonsten eben ohne. Wenn du nicht weißt, wie das geht, dann zur Not (du solltest aber trotzdem besser herausfinden wie ersteres geht) mit einem
#define DEBUGvor den Includes (die debug.h muss natürlich auch eingebunden werden).
Das ist zwar sicher nicht die eleganteste Lösung aber recht unkompliziert.
-
Ah, das klappt.
Vielen Dank, genau so etwas habe ich gesucht.
Das mit dem gesetzten Symbol weiß ich bei momentan Stand leider noch nicht, aber werde das versuchen herauszufinden, sobald ich mit der Aufgabe fertig bin.
Vielen dank.
edit:
Habe noch eine Frage, ist es auch möglich, das ganze nur für bestimmte Codestellen zu implementieren.Sagen wir man hat in der Main erst den Insertion und danach den Selectionsort. Nun habe ich mal versucht
#define DEBUG nach dem Insertion zu setzen, so dass nur der Selectionsort eine Ausgabe hat, das klappt aber nicht.Gibt es also eine Möglichkeit, dass das Weglassen der Ausgabe erst ab einem bestimmten Zeitpunkt einsetzt, ich aber dennoch alle couts umschreiben muss? Ich muss halt einmal mit Ausgabe laufen lassen und danach mit Zufallszahlen ohne Ausgaben die Laufzeit testen.
Und einfach nochmal die Funktion kopieren und alle couts weglassen und diese "neue" Funktion dann aufrufen ist auch nicht das Gelbe vom Ei
-
Das geht dann nicht mit Makros, da diese den zu kompilierenden Code verändern (und somit nur exakt eine Version deiner Funktion in der EXE erzeugt).
Und zur Laufzeit ein- oder ausschalten geht doch einfach mit einem Flag:
bool show_output = true; // bzw. falseals Parameter oder (in diesem Fall) evtl. auch global.
Und dann
if (show_output) { cout << "..."; }Edit: Ich sehe gerade, daß du ja schon templates für deine Sortierfunktion benutzt. Dann ist es sogar noch einfacher, da du das Flag als Template-Parameter benutzen kannst und dann einfach zwei verschiedene Instantiierungen erzeugen kannst:
template <class T, bool ShowOutput> vector<T> insertionsort(vector<T> v1, int abstand = 1) { // ... if (ShowOutput) { cout << "..."; } }Aufruf:
insertionsort<int, true>(...); // mit Ausgabe insertionsort<int, false)(...); // ohne Ausgabe
-
Oh das mit dem Template ist natürlich klasse.
Hatte auch schon daran gedacht eine if Abfrage einzubauen, aber dachte das verbraucht zuviel Zeit und habe es deswegen gelassen.
Aber auf der anderen Seite sollte diese eine if-Abfrage doch zu vernachlässigen sein pro Durchlauf oder nicht?
-
Neutral0815 schrieb:
Aber auf der anderen Seite sollte diese eine if-Abfrage doch zu vernachlässigen sein pro Durchlauf oder nicht?
Auf jeden Fall vernachlässigbar gegenüber einer Ausgabeoperation.
Ich persönlich würde sie einfach ganz rausmachen. Es sind Sortieralgorithmen. Das ist überschaubar. Da weiß man doch nach dem Entwickeln, ob sie funktionieren oder nicht und braucht dann, wenn sie funktionieren, keine Debugausgaben mehr. Ein Performancevergleich zwischen Algorithmen, deren Funktionalität noch nicht sichergestellt ist, ist sinnlos. Alternativ kann ein Teil der Performanceprüfung natürlich auch sein, im Nachhinein auch das Ergebnis zu prüfen. Wer falsch sortiert, fliegt raus.
edit: Bei deinem Code bekommst du mit dem obigen Vorschlag jedoch Probleme. Deine Funktionen haben keine sauber abgesteckte Funktionalität. Sie machen alles. Ankündigung, Durchführung, Ergebnispräsentation. Eine Sortierfunktion sollte nur Sortieren. Dann kann man sie auch losgelöst von anderen Faktoren mit anderen Sortierfunktionen vergleichen.
-
Sorry, das ich was später antworte.
Ja, es ist wahr, dass meine Sortierfunktionen quasi alles machen, aber das will die Aufgabenstellung auch so.
Daran kann ich leider nichts ändern, aber habe nun alles hinbekommen, zwar selbst in meinen Augen meist etwas unschön, aber es läuft zumindest erstmal alles
