Initialisierung .. welche ist effizienter?

8

Ich habe folgende Frage. Welcher von diesen ist besser, der gefolgt werden sollte und warum?

%Vor%

oder

%Vor%

Vielen Dank im Voraus.

    
vj01 12.03.2009, 03:29
quelle

4 Antworten

19

Ich habe darauf hier

geantwortet

Eine Sache, die ich hier in die Antwort einfüge: Keiner benutzt einen Zuweisungsoperator .

Kurze Erklärung für die stringspezifische Sache. std::string hat einen Konstruktor, der ein Argument akzeptiert, das char const* akzeptiert:

%Vor%

Nun sehen Sie, dass ein Konstruktor einen Zeiger auf Zeichen hat. Damit kann ein String-Literal akzeptiert werden. Ich denke, der folgende Fall ist dann offensichtlich:

%Vor%

Er ruft den Konstruktor direkt auf und initialisiert dabei s . Dies wird direkte Initialisierung genannt.

Die andere Art der Initialisierung einer Variablen wird Kopierinitialisierung genannt. Der Standard sagt für den Fall der Kopierinitialisierung, wo der Initialisierer nicht den Typ des Objekts hat, das initialisiert wird, der Initialisierer in den richtigen Typ konvertiert wird.

%Vor%

Zuerst geben wir die Typen an

  • s hat den Typ std :: string
  • "hello" ist ein Array, das in diesem Fall wieder wie ein Zeiger behandelt wird. Wir werden es daher als char const* betrachten.

Der Compiler sucht nach zwei Möglichkeiten, die Konvertierung durchzuführen.

  • Gibt es einen Konvertierungskonstruktor in std :: string?
  • Hat der Initialisierer einen Typ mit einer Konvertierungsoperatorfunktion, die ein std::string ?
  • zurückgibt?

Er erstellt eine temporäre std::string auf eine der Arten, die dann verwendet wird, um das Objekt s zu initialisieren, indem Sie std::string 's Kopierkonstruktor verwenden. Und es sieht std::string hat einen Konvertierungskonstruktor, der den Initialisierer akzeptiert. Es benutzt es also. Am Ende ist es tatsächlich dasselbe wie

%Vor%

Beachten Sie, dass das Formular, das in Ihrem Beispiel verwendet wird, das alles ausgelöst hat

%Vor%

definiert eine implizite Konvertierung . Sie können den Konstruktor mit dem char const* als explizit für Ihre Typen markieren, wenn Sie sich über die Initialisierungsregeln für Ihre Sachen wundern, und es nicht erlauben wird, den entsprechenden Konstruktor als -Konstruktor zu verwenden mehr:

%Vor%

Damit ist es jetzt (und an verschiedenen anderen Stellen) verboten, es mit copy initialization und char const* zu initialisieren!

Nun, das war, wenn der Compiler die Elision von Provisorien an verschiedenen Stellen nicht unterstützt. Der Compiler darf annehmen, dass ein Kopierkonstruktor in diesem Kontext kopiert, und kann die zusätzliche Kopie der temporären Zeichenfolge entfernen und stattdessen die temporäre std :: string direkt in das initialisierte Objekt einbauen. Der Kopierkonstruktor muss jedoch insbesondere zugänglich sein. Daher ist die Kopierinitialisierung ungültig, wenn Sie dies tun

%Vor%

Jetzt ist eigentlich nur der direkte Initialisierungsfall gültig.

    
Johannes Schaub - litb 12.03.2009 03:36
quelle
7

Kompiliere beide, sieh dir den Assembler an. Der erste ist eine weniger Anweisung ...

%Vor%

... aber das ist ein Artefakt, weil es der erste war, den der Compiler gesehen hat. Ändern Sie den Code, indem Sie die Reihenfolge wechseln:

%Vor%

... und siehe da, die Sekunde ist eine Anweisung weniger.

Wir sehen auch, dass dieser Compiler (Microsoft VC ++ 2005, Release-Einstellungen) für beide Versionen den gleichen Assembler generiert hat. Es macht also keinen Unterschied in diesem Compiler, und Sie können es beweisen.

    
Thomas L Holaday 12.03.2009 04:14
quelle
2

Der einzige wirkliche Unterschied besteht darin, dass der erste den Kopierkonstruktor technisch benötigt, aber der Compiler darf ihn verwenden, damit die Effizienz in beiden Fällen identisch ist.

Der erste erfordert jedoch, dass der Kopierkonstruktor zugänglich ist (d. h. nicht privat), selbst wenn er nicht tatsächlich verwendet wird.

    
Drew Hall 12.03.2009 03:54
quelle
1

Die anderen Antworten sind alle korrekt, aber denken Sie bitte auch daran, dass das wahrscheinlich keine Rolle spielt. Es wird selten, sehr selten, unglaublich selten, dass die Effizienz der String-Initialisierung Auswirkungen auf Ihr Programm hat Geschwindigkeit sogar um einen Bruchteil einer Sekunde.

Die Frage selbst ist eine Spaß , weil sie die Operationen von C ++ - Konstruktoren und -Zuordnungen zeigt, aber in der Praxis, wenn Sie Zeit damit verbringen, diese zu optimieren (und die Veröffentlichung auf SO ist Beweis genug) du bist ..) du kippst wirklich Windmühlen.

Es ist besser, die Ablenkung zu vermeiden und sich anderswo zu bemühen.

    
SPWorley 12.03.2009 08:09
quelle

Tags und Links