Lesen über std::unique_ptr
bei http://en.cppreference.com/w/cpp/memory/unique_ptr, mein naive Eindruck ist, dass ein klug genug Compiler die korrekte Verwendung von unique_ptr
mit blanken Zeigern ersetzen könnte und einfach in eine delete
setzen, wenn die unique_ptr
s zerstört werden. Ist das tatsächlich der Fall? Wenn ja, tut dies einer der Mainstream-optimierenden Compiler? Wenn nicht, wäre es möglich, etwas mit einigen/allen unique_ptr
s Kompilierungszeit-Sicherheitsvorteilen zu schreiben, die optimiert werden könnten, um keine Laufzeitkosten (in Raum oder Zeit) zu haben?Könnte ein optimierender Compiler alle Laufzeitkosten von std :: unique_ptr entfernen?
Hinweis für diejenigen (richtig) besorgt über vorzeitige Optimierung: Die Antwort hier wird mich nicht davon abhalten, std::unique_ptr
zu verwenden, bin ich nur neugierig, ob es ein wirklich tolles Werkzeug oder einfach nur ein tolles ist.
EDIT 2013.07.21 20.07 EST:
OK, so dass ich mit folgendem Programm getestet (wissen Sie mich bitte, wenn mit diesem etwas falsch gibt es):
#include <climits>
#include <chrono>
#include <memory>
#include <iostream>
static const size_t iterations = 100;
int main (int argc, char ** argv) {
std::chrono::steady_clock::rep smart[iterations];
std::chrono::steady_clock::rep dumb[iterations];
volatile int contents;
for (size_t i = 0; i < iterations; i++) {
auto start = std::chrono::steady_clock::now();
{
std::unique_ptr<int> smart_ptr(new int(5));
for (unsigned int j = 0; j < UINT_MAX; j++)
contents = *smart_ptr;
}
auto middle = std::chrono::steady_clock::now();
{
int *dumb_ptr = new int(10);
try {
for (unsigned int j = 0; j < UINT_MAX; j++)
contents = *dumb_ptr;
delete dumb_ptr;
} catch (...) {
delete dumb_ptr;
throw;
}
}
auto end = std::chrono::steady_clock::now();
smart[i] = (middle - start).count();
dumb[i] = (end - middle).count();
}
std::chrono::steady_clock::rep smartAvg;
std::chrono::steady_clock::rep dumbAvg;
for (size_t i = 0; i < iterations; i++) {
smartAvg += smart[i];
dumbAvg += dumb[i];
}
smartAvg /= iterations;
dumbAvg /= iterations;
std::cerr << "Smart: " << smartAvg << " Dumb: " << dumbAvg << std::endl;
return contents;
}
Das Kompilieren mit g ++ 4.7.3 unter Verwendung von g++ --std=c++11 -O3 test.cc
ergab Smart: 1130859 Dumb: 1130005
, was bedeutet, dass der intelligente Zeiger innerhalb von 0,076% des dummen Zeigers liegt, was fast sicher Rauschen ist.
Was * sonst * würde ein Compiler möglicherweise tun ?! Ein eindeutiger Zeiger * ist * nur ein einzelner Zeiger, soweit der Dateninhalt der Klasse betroffen ist. –
Welche Laufzeitkosten hat ein 'unique_ptr 'überhaupt? Was Platz angeht, so sind 'sizeof (myuniqueptr)' vs 'sizeof (myptr)' genau die gleichen für mich, 8 Bytes für 'int'. – Rapptz
Nun, das Lesen von http://StackOverflow.com/Questions/8138284/about-unique-PTR-Performances deutet darauf hin, dass einige (frühe?) Implementierungen nicht so waren ... –