prestazioni di dichiarazione di oggetti
Stavo programmando una sorta di conquista universitaria e ho notato qualcosa, quando dichiaro una mappa in un ciclo come in basso:
for (int i = 0; i < n; i++)
{
map<int, bool> hashMap;
//...
}
ci vuole più tempo di:
map<int, bool> hashMap;
for (int i = 0; i < n; i++)
{
hashMap.clear();
//...
}
quindi mi chiedevo perché la dichiarazione di un oggetto in un ciclo ha prestazioni peggiori rispetto alla semplice reinizializzazione?
Risposte
Nella prima versione del codice il costruttore e il distruttore del hashMap
sono chiamati n
tempi, mentre nella seconda versione sono chiamati una sola volta.
La domanda naturale è perché la distruzione e la costruzione di un nuovo map
oggetto sarebbero notevolmente diverse rispetto alla pulizia e al riutilizzo di uno stesso oggetto. Questo può essere risolto definitivamente solo ispezionando il map
codice effettivo dell'implementazione utilizzata, quindi quanto segue è solo un'ipotesi plausibile.
std::mapdi solito è implementato utilizzando alberi rosso-nero , ed è comune per le implementazioni albero rosso-nero utilizzare un nodo sentinella per foglie NIL, vedere ad esempio Vantaggi di un nodo sentinella in un albero rosso nero? . Questa sentinella deve essere assegnata ogni volta che viene costruito un albero, quindi rilasciata dopo la distruzione. Al contrario, clear
'ing a map
svuota l'albero ma riutilizza gli oggetti interni associati.
Per un esempio reale di tale implementazione, il _Treecostruttore di Microsoft chiama il nome appropriato _Alloc_sentinel_and_proxy();
. Poiché map
derivano da _Tree
, questo viene chiamato ogni volta map
che viene costruito un oggetto.