2016-06-02 20 views
7

Diciamo che ho un map<int, int>:vale forse la pena pagare per i tipi di base?

std::map<int, int> map; 

map.emplace(1, 2); 
map.insert({3, 4}); 

Ci sarà qualche differenza tra le due chiamate?

Nella prima chiamata, i due numeri interi verranno copiati per valore nella funzione emplace e quindi di nuovo nel costruttore std::pair<int, int>. Nella seconda chiamata, i due numeri interi verranno copiati in base al valore per il costruttore std::pair<int, int> e quindi copiati di valore per lo std::pair<int, int> interno come membri della prima coppia.

Capisco i vantaggi di emplace per tipi come std::string in cui verrebbero copiati in base al valore nella seconda chiamata e spostati completamente nella prima, ma c'è qualche vantaggio nell'utilizzo di emplace nella situazione descritta?

risposta

11

Emplace è più lento, se c'è una possibilità che il posto non funzionerà (la chiave è già presente).

Questo perché emplace è necessario per allocare un nodo e costruire il pair<Key const, Value> in esso, quindi estrarre la chiave da quel nodo e verificare se la chiave è già presente, quindi rilasciare il nodo se la chiave è già presente. D'altra parte insert può estrarre la chiave dal valore passato da inserire, quindi non è necessario allocare un nodo se l'inserimento fallirebbe. Vedi: performance of emplace is worse than check followed by emplace.

Per risolvere questo problema, C++ 17 aggiunge una funzione membro try_emplace(const key_type& k, Args&&... args) (etc.)

In caso di successo, non v'è alcuna differenza tra i due casi; l'ordine delle operazioni è diverso, ma ciò non influirà sulle prestazioni in alcun modo prevedibile. La dimensione del codice sarà ancora leggermente più grande per la variante emplace, in quanto deve essere pronta per eseguire più lavoro nel caso di errore.