Estou executando a ferramenta cppcheck em algum código e ela me relata um problema de desempenho em algum código ao verificar se um mapa não tem um valor antes de inserir um novo.
Isolei o código em um snippet MCVE (que não faz sentido... mas ilustra o problema):
std::map<int, float*> myMap;
myMap[1] = new float(3.0f);
for ( size_t pos = 0; pos != 10; ++pos )
{
if ( myMap.find( pos ) == myMap.end() )
{
myMap[pos] = new float(4.0f);
}
}
Relatórios CppCheck(performance,ID=stlFindInsert) Searching before insertion is not necessary.
Na verdade, é necessário evitar vazamentos substituindo o valor antigo por um novo... e, a propósito, você pode não querer substituir o valor antigo, se houver algum...
Como devo escrever o código melhor para evitar esse problema de desempenho?
Na verdade, você faz duas pesquisas, enquanto apenas uma é necessária.
Você pode usar
insert
/emplace
em vez disso (e para evitar vazamento de memória, insiranullptr
e substitua):Outra maneira, se você não inseriu o valor padrão no mapa antes, pode ser
Para evitar uma consulta dupla no mapa, você pode procurar o item usando
equal_range
e, em seguida, usarinsert
with passando o resultado da dica do iterador.https://en.cppreference.com/w/cpp/container/map/equal_range
https://en.cppreference.com/w/cpp/container/map/insert
O resultado é que você só paga o tempo logarítmico para inserir o item para a
equal_range
chamada, enquantoinsert
deveria acontecer em tempo constante amortizado