2016-11-10 4 views

Antwort

4

Member-Tausch war eine massive Leistungssteigerung vor std::move Unterstützung in C++ 11. So konnten Sie beispielsweise einen Vektor an einen anderen Ort verschieben. Es wurde in vector Größen ebenso verwendet, und es bedeutete, dass das Einfügen in einen Vektor von Vektoren war nicht vollständige Leistung Selbstmord.

Nach std::move angekommen C++ 11, mit vielen manchmal leeren Typen die Standardimplementierung von std::swap in:

template<class T> 
void swap(T& lhs, T& rhs) { 
    auto tmp = std::move(rhs); 
    rhs = std::move(lhs); 
    lhs = std::move(tmp); 
} 

wird grundsätzlich so schnell wie ein custom-written sein.

Bestehende Typen mit swap Mitgliedern sind unwahrscheinlich, sie (zumindest sofort) zu verlieren. Das Erweitern der API eines neuen Typs sollte jedoch gerechtfertigt sein.

Wenn std::future im Grunde ein Wrapper um ein std::unique_ptr<future_impl> ist, dann wird das obige 4 Zeiger Lesevorgänge, 3 Zeiger Schreibvorgänge und einen Zweig erfordern. Und ein optimierender Compiler, der ihn in die Zeile einfügte, konnte ihn auf 2 Zeigerlesevorgänge und 2 Zeigerschreibvorgänge reduzieren (unter Verwendung von SSA zum Beispiel), was eine optimierte .swap Elementfunktion tun könnte.


So weiß es Zwischen Zugang zum lhs und rhs nie auftritt, also die Existenz von tmp kann als-ob beseitigt werden, sobald es beweist tmp ist leer und hat daher eine no-op dtor.

Static single assignment, wobei Sie ein Programm so abbrechen, dass jede Zuweisung zu einem Primitiv eine brandneue Variable (mit Metadaten) erstellt. Sie beweisen dann Eigenschaften über diese Variable und eliminieren redundante.

+0

Warum funktioniert eine Mitgliedsfunktion und nicht ein Freund für unqualifiziertes 'swap'? - Ich habe den Eindruck, dass gcc (4.8) bei der Optimierung von 'unique_ptr' schlecht ist. Obwohl es SSE verwendet, führt es viele unnötige Operationen durch. Vielleicht wegen der Ausnahmebehandlung, aber vielleicht auch, weil libstdC++ ''unique_ptr' ein' tuple' verwendet, um das komprimierte Paar aus Delet und Pointer zu implementieren, und Tupel könnte ziemlich schwer zu optimieren sein. – dyp

+0

@dyp Klingt nach einem Grund, Ihren Optimierer besser zu machen, anstatt die Sprache zu ändern. Oder finde einen Weg, das komprimierte Tupel-Idiom als ein schwer zu optimierendes bibliotheksbasiertes 'Tupel' auszudrücken; wenn komprimiertes 'tuple' schwer zu optimieren ist, vielleicht ein' std :: tuple'? Das geht wahrscheinlich zu weit; dann ein eingebauter primitiver Produkttyp, der die Implementierung von komprimiertem 'std :: tuple 'vereinfacht? – Yakk

+0

libC++ hat einen dedizierten 'compressed_pair' Typ, ich denke das hilft schon. Zumindest mit Kompilierzeiten. Ich habe mich über die Performance gewundert, da Howard Hinnant aus Performancegründen die Copy/Move + Swap-Sprache nicht mag. – dyp

Verwandte Themen