Liste möglichst Performant (so wenig Vergleiche wie möglich) ausgeben
-
Folgendes Problem, ich habe ne Liste und möchte deren Inhalt nun ausgeben.
struct meine_liste { char* daten; struct meine_liste *next; // Verweist auf nächstes Listenelement } struct meine_liste *hilf; // Mein Hilfszeiger, mit dem arbeite ich. /* Hier kommt noch etwas Code, ist aber unwesentlich für die Frage */
Bei der Ausgabe ist das 1. Listenelement auf jedenfall mit Daten gefüllt,
daher habe ich mir gedacht, ich nehme ne do while Schleife um einen Vergleich am Anfang einzusparen:do { printf("....usw. // hier geben wir den Inhalt des aktuellen Listenelements aus // und nun müssen wir den Hilfszeiger auf das nächste Listenelement zeigen lassen if (hilf->next != 0) // und genau hier ist das Problem, siehe weiter unten. Bei * { hilf = hilf->next; } ... // usw. } while(hilf->next != 0); // Mache solange in der Schleife weiter, solange ein neues Listenelement vorhanden ist
* Und genau da ist das Problem:
Denn ob hilf->next != 0 ist, wird bei jedem Schleifendurchgang 2 mal überprüft.
Das erste mal im While Kopf (oder du while Fuß) und das nächste mal bei der Zuweisung, bzw der if abfrage ob ich zuweisen kann.Wenn ich aber diese Abfrage in einer normalen while Schleife einbaue:
while (hilf->next !=0) { printf(... // usw. gibt Listeninhalt aus usw. }
Dann kann ich mir die If Abfrage sparen,
aber dann muß ich nach der while Abfrage die Daten des aktuellen letzten Listenelements extra ausgeben, da diese ja nicht ausgegeben werden, da hilf.next ja durchaus NULL sein kann, aber hilf.str dennoch Daten enthalten kann.D.h. mit dieser Lösung hätte ich mindestens 2 * printf, einmal innerhalb und einmal außerhalb der while Schleife.
Meine Frage ist nun, geht das nicht irgendwie eleganter?Also nur eine hilf->next != 0 Überprüfung und nur ein printf Ausdruck um den Inhalt aller Listenelemente in einer Schleife auszugeben?
Hat hier jemand eine Lösung und geht das überhaupt?
-
do { /* Ausgabe */ hilf = hilf->next; } while (hilf != 0);
?
-
Bashar schrieb:
do { /* Ausgabe */ hilf = hilf->next; } while (hilf != 0);
?
Öhm, tja ich stand wohl auf dem Schlauch oder habe noch zu wenig Erfahrung.
Dein Vorschlag ist aber genial!
-
Anfänger 4 schrieb:
Bashar schrieb:
do { /* Ausgabe */ hilf = hilf->next; } while (hilf != 0);
?
Öhm, tja ich stand wohl auf dem Schlauch oder habe noch zu wenig Erfahrung.
Dein Vorschlag ist aber genial!Typ *hilf;
for (hilf = first; hilf != NULL; hilf = hilf->next)
{...}Schöner. Funktioniert auch wenn erster Knoten null ist.
-
Manche Kompiler optimieren schlecht,
außerdem kann ich das besser lesen, weil es einfacher ist:Typ *hilf; for (hilf = first; hilf; hilf = hilf->next) {...}
Gruß Frank
-
Ist eine for Schleife einer while Schleife grundsätzlich vorzuziehen, wenn es um den Compiler geht?
-
Dem Compiler ist das ziemlich egal. Ich würde auch normalerweise die do-while-Schleife nicht benutzen, das hab ich nur gemacht, weil du explizit eine wolltest. Ob while oder for entscheidet sich bei mir danach, ob ich die Laufvariable danach noch brauche oder nicht.
-
Anfänger 4 schrieb:
Ist eine for Schleife einer while Schleife grundsätzlich vorzuziehen, wenn es um den Compiler geht?
Nein. Der MSVC6 hatte for-Schleifen noch erstaunlicherweise bevorzugt, also meßbar schnelleren Code gebaut. Aber ich denke, das ist Geschichte und heute nicht mehr von Belang.
-
@Anfänger 4:
Kleiner Tip: wenn du so einen schweren Schlachtkreuzer wie printf() aufrufst, dann kannst du zig unnötige Vergleiche in der Schleife machen, ohne dass du einen Unterschied in der Laufzeit feststellen wirst.
Also bei sowas nicht auf Geschwindigkeit optimieren, sondern auf Lesbarkeit.
Das Ergebnis ist in dem Fall das selbe, allerdings ist das nicht immer so
-
volkard schrieb:
Nein. Der MSVC6 hatte for-Schleifen noch erstaunlicherweise bevorzugt, also meßbar schnelleren Code gebaut.
Irgendeine Theorie, wieso? Da man ohne große Verrenkungen jede while-Schleife auch als for-Schleife schreiben kann und umgekehrt, ist das ja erstmal alles andere als einleuchtend.
-
Bashar schrieb:
Irgendeine Theorie, wieso?
Ja, Theorie, daß dazwischen ein "sehender Optimierer" war, der typische Schleifenkonstrukte, die in Vergleichsmessungen vorkommen, in handoptimierten ASM übersetzte.