Переменная цикла на основе диапазона for цикл копируется из элементов диапазона вместо ссылки, что приводит к неэффективному коду
Этот дефект возникает, когда переменная цикла основана на диапазоне for цикл копируется из элементов диапазона вместо считывания элементов диапазона по ссылке. Скопируйте элементы диапазона только тогда, когда это необходимо, поскольку их копирование может привести к неэффективному коду. Этот дефект возникает, когда переменная цикла не изменяется и выполняется любое из следующих условий:
Скопированная переменная цикла является большой тривиально копируемой переменной типа. Копирование тривиально копируемого объекта дороже, чем ссылка на него, когда объект большой.
Скопированная переменная цикла является нетривиально копируемым типом. Копирование такого объекта может потребовать вызова внешней функции, что дороже, чем ссылка на него. Чтобы проверить, является ли объект нетривиально копируемым, используйте функцию std::is_trivially_copyable. Дополнительные сведения об этой функции см. в разделе std::is_trivially_copyable в ссылке C++.
На основе диапазона for циклы могут стать неэффективными, когда в каждой итерации цикла создается дорогостоящая копия переменной цикла. Рассмотрим этот код:
void foo( std::map<std::string, std::string> const& property_map )
{
for( std::pair< const std::string, std::string > const property: property_map)
{}
}Переменная цикла property объявлен как const вместо const&. В каждой итерации for цикл, std::pair объект копируется с карты property_maps к переменной цикла property. Из-за пропавшего & в декларации propertдорогостоящая операция копирования выполняется в каждой итерации вместо операции ссылки, что приводит к неэффективному коду. Поскольку этот код компилируется и функционирует правильно, неэффективное for петли могут быть не замечены. Аналогичный источник неэффективности см. в разделе Expensive pass by value и Expensive return by value.
Чтобы устранить этот дефект, объявите переменную цикла на основе диапазона for цикл как const&. Рассмотрим этот код:
void foo( std::map<std::string, std::string> const& property_map )
{
for( std::pair< const std::string, std::string > const& property: property_map)
{}
}property объявлен как const&, переменная ссылается на другой элемент карты property_map в каждой итерации цикла без копирования какого-либо ресурса. Предотвращая дорогостоящую копию в каждой итерации, код становится более эффективным.Повышение производительности может зависеть от используемого компилятора, реализации библиотеки и среды.
| Группа: Производительность |
| Язык: C++ |
| По умолчанию: Откл. |
Синтаксис командной строки:
EXPENSIVE_RANGE_BASED_FOR_LOOP_ITERATION |
| Воздействие: среднее |
Expensive local variable copy | Expensive pass by value | Expensive return by value | Find defects (-checkers)