Seit einiger Zeit können wir viel hören, dass Semantik in C ++ wirklich wichtig ist (zB hier und < a href="http://cpp-next.com/archive/2009/08/want-speed-pass-by-value"> hier ). Ich weiß, dass wir es verwenden sollten, besonders wenn wir den Wert in den Körper der Funktion kopieren wollen. Also ich gehe davon aus, dass eine solche Verwendung fair ist:
%Vor%Ich fand jedoch keine Empfehlung, was zu tun ist, wenn ich dieses Argument durch einen großen Baum von Funktionen leiten muss, der manchmal in einem großen Projekt passiert. Also zum Beispiel:
%Vor%Kann jemand in so einem Fall empfehlen, was zu tun ist? Sollten wir bei der Wertesemantik bleiben und hoffen, dass der Compiler-Optimierer die Anzahl der Verschiebungsoperationen begrenzen oder Const-Referenzen überall und nur eine Kopie am Ende verwenden kann? Oder, wie in vielen Fällen in C ++, hängt es davon ab (d. H. Kosten für Kopieren und Verschieben für einen bestimmten Typ)? : -)
Im Allgemeinen hängt es von den Kopierkosten ab und bewegt sich für bestimmte Typen (und sogar Objekte) und wie es aufgerufen wird (mit temporären oder nicht, usw.)
Zum Beispiel für temporäre boo(gimme_t())
:
Lassen Sie d
ist die Tiefe des Baumes Ihrer Klassen
Lösung mit move
s Kosten d * COST_OF_MOVE
, Lösung mit COST_OF_COPY + d * REF_ASSIGNMENT
.
Sie können sehen, dass für std::string
es O(d)
vs O(n)
ist, also für Strings mit großen Längen ist es billiger Züge zu benutzen (und für kurze Strings ist es nicht so wichtig), aber für std::array<int>
ist es O(nd)
vs O(n + d)
, also solltest du besser eine Kopie verwenden.
Wenn das Argument jedoch nicht temporär ist ( T t; boo(t)
), sind die Kosten wie folgt:
COST_OF_COPY + d * COST_OF_MOVE
vs COST_OF_COPY + d * REF_ASSIGNMENT
, also ist const-ref-Lösung um d
schneller.
Aber wenn du move
fast free ™ in Betracht ziehst, solltest du move solution verwenden, um 1 Kopie im Falle eines temporären Arguments zu vermeiden.
(*) Überall sollten Sie d ± 1
anstelle von d
Für Vorlagen und vorlagenähnliche Lösungen sollte man natürlich mit perfekter Weiterleitung gehen. In anderen Fällen scheint das Erzwingen einer Kopie über foo(MyType copy)
declaration Nadeln zu sein. Vermeiden Sie Kosten, und kopieren Sie, wenn Sie müssen, auch wenn der Compiler durch copy-elision etwas effizienter sein könnte als Verschiebeoperationen.