In diesem Vortrag von Sutter um 1:15:26 wurde ein Code wie unten präsentiert,
%Vor% Ich weiß, wie std::forward
funktioniert, wenn name
ein lvalue ist, name_
wird eine Kopie erstellt; und wenn name
ein rvalue ist, wird name_
die Bewegung konstruiert bekommen. Aber auf der Folie steht auch, dass Optimized to steal from rvalues (and more)
, was ist mehr?
Und später zeigt es, dass dieser Code unter allen vier Implementierungen am schnellsten scheint, besonders für char *
, jeder hat die Geduld, diesen Code durchzugehen und zu erklären, was mehr optimiert wird und warum es am schnellsten ist, besonders in der Fall von char *
?
Beachten Sie zunächst, dass der Code einen Tippfehler enthält und dass die Einschränkung enable_if
nicht das tut, was auch bei entferntem Tippfehler besprochen wird; Insbesondere funktioniert die Funktion nicht mit char*
, also ist es offensichtlich nicht die schnellste mit char*
. Sie können eine Frage zu diesem hier sehen, zusammen mit einem "korrigierten" perfekten Weiterleitungssetter (zusammen mit der Bestätigung dafür Version von Howard Hinnant).
Der Benchmark, der für die Präsentation verwendet wird, ruft set_name
wiederholt auf einem employee
auf, um den Fall anzuzeigen, in dem das Mitglied string
seine Kapazität wiederverwenden kann und nicht bei jeder Iteration eine Speicherzuordnung vorhanden ist. Der Unterschied zwischen den hohen Balken und den kurzen Balken, die in den Benchmarks gezeigt werden, ist der Unterschied zwischen der Wiederverwendung von Kapazität und der Ausführung einer Zuweisung bei jeder Iteration.
Der Grund, warum der korrigierte perfekte Weiterleiter mit char*
schnell ist, liegt daran, dass die Instanziierung des Templates für char*
nur einen char*
weiterleitet, anstatt einen string
Parameter zu konstruieren, um set_name
mit aufzurufen ein tatsächlicher string
-Objektparameter. Die Zuordnung innerhalb des Setter ist schnell, weil string
implementiert operator=(char*)
, die das effiziente memcpy in seinen vorhandenen Speicher tut und zusätzliche Zuweisungen vermieden werden.
Der Anspruch Optimized to steal from rvalues (and more)
liegt also daran, dass die perfekte Weiterleitung nichts weiter als Weiterleitung macht. Es durchläuft nicht nur einen R-Wert, wenn es einen R-Wert erhält, sondern es konvertiert auch keine Typen, was bedeutet, dass Optimierungen, die der "Forwardee" implementiert, wie string
's operator=(char*)
ebenfalls angezeigt werden.