Quale modo è più efficace/accettabile/leggibile?
La soluzione if
/else
è il più efficiente se avete solo un paio di valori, ed è certamente abbastanza semplice soprattutto per le persone non utilizzati per la libreria standard, tuttavia devolve rapidamente in un pasticcio.
Pertanto, non appena si raggiunge un 5 o più articoli, passare a utilizzare un contenitore.
Avvertenza: sfortunatamente, std::string_view
, che eviterebbe un'allocazione di memoria, non è ancora standard; per semplicità userò quindi std::string
, anche se se l'allocazione di memoria è un problema, std::string_view
o una classe personalizzata CStr
sarebbe meglio.
Ci sono 3 scelte valide:
std::map<std::string, int>
e std::unordered_map<std::string, int>
sono le scelte più intuitivi, non è chiaro che sarebbe stato più veloce
std::vector<std::pair<std::string, int>>
(ordinate) sarà sempre più efficiente di std::map<std::string, int>
Quindi, se l'efficienza è un problema:
int convert(std::string const& name) {
static std::vector<std::pair<std::string, int>> const Table = []() {
std::vector<std::pair<std::string, int>> result = {
{ "one", 1 },
{ "two", 2 },
{ "three", 3 },
{ "four", 4 }
};
std::sort(result.begin(), result.end());
return result;
}();
auto const it =
std::lower_bound(Table.begin(), Table.end(), std::make_pair(name, 0));
if (it != Table.end() and it->first == name) {
return it->second;
}
return 0;
}
Un array ordinato è, dopo tutto, il modo più efficiente per eseguire una ricerca binaria, a causa di un comportamento migliore della cache. Dovrebbe anche sovraperformare std::unordered_map
su input piccoli per gli stessi motivi.
Ovviamente, è leggermente meno leggibile.
È necessario chiarire la cardinalità e la frequenza di risposta. Se hai un paio di stringhe, o la maggior parte delle hit sono per un piccolo sottoinsieme di stringhe, allora il primo. Ma in generale, a partire da una dozzina di stringhe - la successiva. Non dimenticare di contare l'overhead della prima chiamata alla variante successiva. In generale, IME, il successivo è migliore, dal momento che è più facile da mantenere. – Dummy00001
@ChrisDrew Sei corretto. Sono venuto a cercare dall'altra parte e non ho guardato il codice abbastanza da vicino. – NathanOliver
Risposta classica: definire efficace/accettabile/leggibile – Drop