Expensive use of container's count method

Функциональный член count() из контейнера используется для проверки, если ключ присутствует, ведя к неэффективному коду

Описание

Этот дефект повышен когда функциональный член count() из этих контейнеров называется для проверки, если ключ присутствует:

  • std::multimap

  • std::multiset

  • std::unordered_multiset

  • std::unordered_multimap

При проверке включения вы преобразуете выход count() контейнера метод к bool, или сравните его с любым 0 или 1.

Риск

count функция предыдущих контейнеров выполняет линейный поиск и находит все экземпляры ключа в контейнере. Когда проверка, присутствует ли ключ в контейнере, выполняя исчерпывающий поиск каждого экземпляра ключа, является ненужной и неэффективной.

Исправление

Чтобы зафиксировать этот дефект, вызовите член find или contains функция контейнера при проверке на включение. Эти функции прекращают искать ключ, как только один экземпляр ключа найден. Эти функции проверяют включение более эффективно по сравнению с count функция.

Повышения производительности могут варьироваться на основе компилятора, реализации библиотеки и среды, которую вы используете.

Примеры

развернуть все

#include <unordered_set>
#include <unordered_map>
#include <set>
#include <map>
#include <algorithm>
#include <string>

typedef std::string V;  
typedef std::string K;  


void conatins()
{
	std::string key;
	std::pair<const K, V> kv;

	
	std::multiset<V> ms;
	std::multimap<K, V> mm;
	std::unordered_multimap<K, V> umm;
	std::unordered_multiset<K> ums;
	
	//Check containment
	
	bool b_ms = (ms.count(key)==0);  //Noncompliant
	bool b_mm = (mm.count(key)==0);//Noncompliant
	bool b_ums = (ums.count(key)==0);//Noncompliant
	bool b_umm = (umm.count(key)==0);//Noncompliant

}

В этом примере, Polyspace® отмечает использование функции количества члена, чтобы проверять включение в различные контейнеры. Эти функции количества неэффективны, потому что они продолжают искать key даже после того, как первая инстанция найдена.

Коррекция

Чтобы зафиксировать этот дефект, использование член находят, что функция проверяет на включение. Например, используйте std::multimap::find вместо std::multimap::count. Искать функции более эффективны, потому что они прекращают искать как только первая инстанция key найден.

#include <unordered_set>
#include <unordered_map>
#include <set>
#include <map>
#include <algorithm>
#include <string>

typedef std::string V; 
typedef std::string K; 

void conatins()
{
	std::string key;
	std::pair<const K, V> kv;

	
	std::multiset<V> ms;
	std::multimap<K, V> mm;
	std::unordered_multimap<K, V> umm;
	std::unordered_multiset<K> ums;
	
	//Check containment
	
	bool b_ms = (ms.find(key)== ms.end());  //Compliant
	bool b_mm = (mm.find(key)== mm.end());//Compliant
	bool b_ums = (ums.find(key)==ums.end());//Compliant
	bool b_umm = (umm.find(key)==umm.end());//Compliant

}

Информация о результате

Группа: Производительность
Язык: C++
Значение по умолчанию: Off
Синтаксис командной строки: EXPENSIVE_CONTAINER_COUNT
Удар: Средняя
Введенный в R2021b