Zum Inhalt springen

Referenz vs. lokale Kopie


Raute50

Empfohlene Beiträge

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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?

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 Wochen später...

@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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...