Raute50 Geschrieben 8. August 2006 Geschrieben 8. August 2006 MahlZeit! Ich sitze momentan an einem C++ Software Projekt und habe eine grundlegende Frage, die hoffentlich von einem erfahrenen Programmierer schnell beantwortet werden kann. Es geht um die Frage was schneller ist, einer Funktion eine Referenz zu uebergeben und mit dieser zu arbeiten oder eine lokale Kopie zu erstellen und am Ende der Referenz den Inhalt zuzuweisen. Durch folgenden Code wurde das ausprobiert und im grossen Umfang getestet. multiply ist eine Member-Funktion von MontgRep. Der Datentyp "MontgRep" besteht aus einem plus- und einem minus-Teil, die jeweils Datentyp vec_ZZ_p ( Vektoren ) sind. void multiply(MontgRep &a, const int &A_temp) { vec_ZZ_p thevecp,thevecm; // das sind spezielle Vektoren thevecp.SetLength(plus.length()); thevecm.SetLength(plus.length()); for (int i=plus.length()-1; i>=0; i--) { thevecp[i] = a.plus[i]*A_temp; thevecm[i] = a.minus[i]*A_temp; } plus=thevecp; minus=thevecm; } Im Gegensatz zu void multiply(MontgRep &a, const int &B_temp) { //Folgender Code geht auch ist aber langsamer!!!!! for (int i=plus.length()-1; i>=0; i--) { plus[i] = a.plus[i] * B_temp; minus[i] = a.minus[i] * B_temp; } } Eigentlich dachte ich, dass es fuer solch grundlegende Sachen zu viel Aufwand ist, noch zusaetzlich lokale Objekte zu erstellen ( auch wenn sie nicht so gross sind ), wenn man schon Speicher fuer das referenzierte Objekt zur Verfuegung hat, welchen man doch auch nutzen kann ( mir wurde sogar mal geraten, dass man den auch nutzen sollte ). Aber es hat sich herausgestellt, dass das Arbeiten mit einer erstellten einer Kopie und abschliessendem Zuweisen der Werte auf das referenzierte Objekt schneller geht!? Dieses wurde dann versucht auf andere Funktionen anzuwenden, jedoch mit unterschiedlichem Erfolg, sprich es wurde an anderer Stelle mit voellig aequivalenter Herangehensweise langsamer. Das richt in meiner Nase nach einer speziellen Benutzung von Referenzen. Da diese mir einfach noch nicht bekannt ist, hoffe auf diesem Wege einen Rat zu bekommen. Hinweise auf Buecher, die das gut umschreiben, werden natuerlich auch dankend angemommen, falls jemand damit dienen kann ... ! Ueber Reaktionen waere ich natuerlich sehr dankbar! MfG #50 Zitieren
baba007 Geschrieben 8. August 2006 Geschrieben 8. August 2006 du brauchst keinen Programmierprofi sondern einen Kompiler/OS Guru. Das Verhalten ist da wie Tag und Nacht. Sun Solaris zum Beispiel macht eine Kopie und arbeitet mit dieser, wenn fertig dann schreibt er den Rest in den Speicher, das kann, je nach Größe zu Programmierfehlern und Verzögerung kommen. Ich habe noch vor kurzem ein C-Programm entwickelt, dass mehrere Megabyte Daten hin und her schob oder erstellte. Mit Call by Ref. war es sehr mühsam und Fehleranfällig bei Portierung. Das ist meine Erfahrung diesbezüglich Zitieren
Bubble Geschrieben 8. August 2006 Geschrieben 8. August 2006 Solaris zum Beispiel macht eine Kopie und arbeitet mit dieser, wenn fertig dann schreibt er den Rest in den Speicher, das kann, je nach Größe zu Programmierfehlern und Verzögerung kommen. Solaris ist ein Betriebssystem, es hat mit dem internen Aufbau des Programms im Zusammenhang mit der gestellten Frage nichts zu tun... @Raute50: Leider ist der von Die gepostete Codeausschnitt zu knapp, um mögliche Gründe finden zu können. Wie schnell ein Programm letztlich ist, hängt auch vond en Optimierungend es Compilers ab. Welchen Compiler verwendest Du mit welchen Optimierungen? Um zu verstehen, was den Unterschied ausmacht, kann es auch hilfreich sein, sich den vom Compiler erzeugen Assembler-Code anzusehen und beide Varianten zu vergleichen. Die zweite von Dir genannte Variante könnte langsamer sein, wenn intern jedes Mal erneut this->plus ausgewertet wird, während bei der anderen Variante dieses entfällt bzw. so optimiert wurde, dass nur ein Zeiger verwendet wird. Was der tatsächliche Unterschied ist, kann Dir aber nur ein Blick in den Assember-Code sagen. Abgesehen davon: Warum lässt Du Deine Schleife rückwärts zählen? Zitieren
Raute50 Geschrieben 16. August 2006 Autor Geschrieben 16. August 2006 @Raute50: Leider ist der von Die gepostete Codeausschnitt zu knapp, um mögliche Gründe finden zu können. Wie schnell ein Programm letztlich ist, hängt auch vond en Optimierungend es Compilers ab. Welchen Compiler verwendest Du mit welchen Optimierungen? Um zu verstehen, was den Unterschied ausmacht, kann es auch hilfreich sein, sich den vom Compiler erzeugen Assembler-Code anzusehen und beide Varianten zu vergleichen. Die zweite von Dir genannte Variante könnte langsamer sein, wenn intern jedes Mal erneut this->plus ausgewertet wird, während bei der anderen Variante dieses entfällt bzw. so optimiert wurde, dass nur ein Zeiger verwendet wird. Was der tatsächliche Unterschied ist, kann Dir aber nur ein Blick in den Assember-Code sagen. Abgesehen davon: Warum lässt Du Deine Schleife rückwärts zählen? Also erst mal danke für die Antworten .... Wir verwenden den g++ Compiler mit -O3 ( nun ... vorher ohne Optimierung ) .... Von Assembler haben wir KEINE Ahnung ... :-( Haben jetzt auch mit einigen Tests versucht ein vernünftiges Mittel herausgefunden, in unseren Speziellen Fällen darauf zu reagieren ... manchmal mit eigenartigen Ergebnissen .... Das Multiply wird SEHR OFT aufgerufen und die Einträge sind oft SEHR LANG. Deswegen rufe ich nur 1x die .length() auf und zähle rückwärts um ( Anzahl der Aufrufe x ( Länge -1 ) ) Aufrufe zu sparen .... In diesem Sinne ... #50 Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.