Effizienzfrage Variablenzuweisung
-
Hallo.
was ist effizienter und warum?
Dies:
double timestamp = getTimeStamp();oder das:
double timestamp(getTimeStamp());Meiner Meinung nach sollte die 2te Variante günstiger sein, da das double Objekt direkt mit einem copy-Konstruktor initialisiert wird. Im ersten Fall wird das Objekt ja erst angelegt und dann zugewiesen. Ist das korrekt?
Wenn ja: Sollte dann nicht auch jede for-schleife so aussehen?
for (int i(0); i < Bedingung; ++i) ?Danke.
-
Erhard schrieb:
Meiner Meinung nach sollte die 2te Variante günstiger sein, da das double Objekt direkt mit einem copy-Konstruktor initialisiert wird. Im ersten Fall wird das Objekt ja erst angelegt und dann zugewiesen. Ist das korrekt?
Nein. Grundsätzlich wird das objekt sofort initialisiert. Allerdings hat die Schreibweise
T a = bformal die Bedeutung, dass zuerst ein temporäres Objekt vom Typ T angelegt wird und dann a mit dem temporären Objekt copy-initlaisiert wird. In der Praxis optimieren so ziemlich alle Compiler das temporäre Objekt weg. AFAIK ists sogar bei PODs schon von vornherein ohne die Kopie festgelegt.
-
Probiere es aus! Schreibe eine Klasse mit default, init und copy constructor , sowie einen Zuweisungsoperator und schaue dir das Verhalten an.
#include <iostream> class Testy { public: Testy() { std::cout << "default" << std::endl; } Testy( const Testy& ) { std::cout << "copy" << std::endl; } Testy& operator=( const Testy& testy ) { std::cout << "assign" << std::endl; } }; int main() { Testy a; Testy b = a; Testy c; c = a; return 0; }Es hat auch nichts mit Compileroptimierung zu tun. "Testy b = a" hat die Semantik einer Kopierkonstruktion, auch wenn es nicht so aussieht. Zeile 14 ist eben nicht aequivalent zu Zeile 15+16.
-
-
Erhard schrieb:
Meiner Meinung nach sollte die 2te Variante günstiger sein, da das double Objekt direkt mit einem copy-Konstruktor initialisiert wird. Im ersten Fall wird das Objekt ja erst angelegt und dann zugewiesen. Ist das korrekt?
Welche Meinung du dazu hast, spielt an sich keine Rolle, double ist keine Klasse und hat keinen copy-Konstruktor und eine Initialisierung ist keine Zuweisung. Dass der Speicher für ein Objekt zunächst reserviert werden muss, bevor in diesem reservierten Speicher ein Wert abgelegt werden kann, ist trivial und hat nichts mit der Schreibweise zu tun. Also: nein.
Meinungssache ist hingehen dies:
double timestamp = getTimeStamp(); // (1) double timestamp(getTimeStamp()); // (2)dass (2) bei weitem hässlicher und schwerer zu verstehen ist (im Sinne von Zeitaufwand, um mit den Augen alle Klammern auseinander zu nehmen). Das ist meine Meinung dazu.
pumuckl schrieb:
Grundsätzlich wird das objekt sofort initialisiert. Allerdings hat die Schreibweise
T a = bformal die Bedeutung, dass zuerst ein temporäres Objekt vom Typ T angelegt wird und dann a mit dem temporären Objekt copy-initlaisiert wird.Das klingt widersprüchlich. Gibt es einen Unterschied zwischen formaler und tatsächlicher Bedeutung? Zudem ist der zweite Satz falsch weil zu allgemein gehalten (selbst wenn wir Referenzen und Arrays von vornherein ignorieren):
Bei der InitialisierungT a = bkann ein temporäres Objekt dann und nur dann entstehen, wenn
1. T eine Klasse ist und
2. der cv-unqualifizierte Typ von b nicht T oder eine von T abgeleitete Klasse ist,
als Folge einer impliziten Konvertierung. Dieses temporäre Objekt kann gemäß 12.8/15 stets eliminiert werden, sofern es den Typ T hat - auf besondere Eigenschaften von T kommt es dabei nicht an. Sind obige Bedingungen nicht erfüllt, besteht, abgesehen vom Fall expliziter Copy-Konstruktoren, keinerlei Bedeutungsunterschied zwischen direkter und Copy-Initialisierung.Ist T ein Skalar, so sind temporäre Objekte von vornherein nicht im Spiel.
Skalare temporäre Objekte entstehen nur, wenn ein rvalue an eine const-Referenz gebunden wird, oder ein eine entsprechende Exception geworfen wird,
-

camper schrieb:
[...] als Folge einer impliziten Konvertierung. Dieses temporäre Objekt kann gemäß 12.8/15 stets eliminiert werden, sofern es den Typ T hat [...]
Kannste mir grad mal ein Beispiel geben, wo dieses temporöre Objekt nicht vom Typ T ist?
Gruß,
SP
-
Sebastian Pizer schrieb:
Kannste mir grad mal ein Beispiel geben, wo dieses temporöre Objekt nicht vom Typ T ist?
Es kann auch ein abgeleiteter Typ sein:
struct foo {}; struct foo_derived : foo {}; struct bar { operator foo_derived() { return foo_derived(); } }; bar x; foo y = x;
-
Besten Dank! War mir nicht bewusst, der Fall.