Verschiebungsoperationen (wie der Verschiebungskonstruktor) für std::shared_ptr
sind billig , da sie im Grunde genommen "Zeiger stehlen" (von Quelle zu Ziel; genauer gesagt, der gesamte Statussteuerblock wird von Quelle zu Ziel "gestohlen", einschließlich der Referenzzählinformationen). .
Stattdessen erhöhen sich die Kopiervorgänge beim std::shared_ptr
Aufrufen der Anzahl der Atomreferenzen (dh nicht nur ++RefCount
bei einem ganzzahligen RefCount
Datenelement, sondern z. B. beim Aufrufen InterlockedIncrement
von Windows), was teurer ist als nur das Stehlen von Zeigern / Status.
Analyse der Ref-Count-Dynamik dieses Falls im Detail:
// shared_ptr<CompilerInvocation> sp;
compilerInstance.setInvocation(sp);
Wenn Sie einen sp
Wert übergeben und dann eine Kopie innerhalb der CompilerInstance::setInvocation
Methode erstellen, haben Sie:
- Bei der Eingabe der Methode wird der
shared_ptr
Parameter kopierkonstruiert: ref count atomares Inkrement .
- Innerhalb des Hauptteils der Methode kopieren Sie den
shared_ptr
Parameter in das Datenelement: ref count atomares Inkrement .
- Beim Beenden der Methode wird der
shared_ptr
Parameter zerstört: ref count atomares Dekrement .
Sie haben zwei atomare Inkremente und ein atomares Dekrement für insgesamt drei atomare Operationen.
Wenn Sie stattdessen den shared_ptr
Parameter als Wert und dann std::move
innerhalb der Methode übergeben (wie in Clangs Code korrekt ausgeführt), haben Sie:
- Bei der Eingabe der Methode wird der
shared_ptr
Parameter kopierkonstruiert: ref count atomares Inkrement .
- Innerhalb des Methodenkörpers geben Sie
std::move
den shared_ptr
Parameter in das Datenelement ein: ref count ändert sich nicht ! Sie stehlen nur Zeiger / Status: Es sind keine teuren atomaren Ref-Count-Operationen erforderlich.
- Beim Beenden der Methode wird der
shared_ptr
Parameter zerstört. Aber seit Sie in Schritt 2 umgezogen sind, gibt es nichts zu zerstören, da der shared_ptr
Parameter auf nichts mehr zeigt. Auch in diesem Fall findet keine atomare Dekrementierung statt.
Fazit: In diesem Fall erhalten Sie nur ein Atominkrement für die Ref-Anzahl, dh nur eine Atomoperation .
Wie Sie sehen können, ist dies viel besser als zwei atomare Inkremente plus ein atomares Dekrement (für insgesamt drei atomare Operationen) für den Kopierfall.