Expensive use of std::string methods instead of more efficient overload

std::string метод вызван строковым литералом известной длины вместо одного заключенного в кавычки символа

Описание

Этот дефект происходит, когда вы вызываете определенный std::string методы со строковым литералом известной длины вместо одного заключенного в кавычки символа. Когда определенный std::string методы вызваны строковым литералом, метод должен вычислить длину литерала даже при том, что информация известна во время компиляции. Polyspace отмечает такие вызовы как неэффективные. Например, Polyspace® отмечает первые два вызова std::string::find:

std::string str;
//...
str.find("A");//Inefficient
//...
str.find("ABC",offset,1);//Inefficient
str.find('A');//Efficient
В первых двух вызовах компилятор вычисляет длину строкового литерала "A", когда это уже известно перед временем выполнения. В третьем вызове компилятор не вычисляет длину входа, выполняя вызов, более эффективный, чем первые два. Polyspace повышает этот дефект когда они std::string методы вызываются при помощи строкового литерала известной длины вместо одного заключенного в кавычки символа:

  • find

  • rfind

  • find_first_of

  • find_last_of

  • find_first_not_of

  • find_last_not_of

  • replace

  • operator=

  • operator+=

  • starts_with (C++ 20)

  • ends_with (C++ 20)

Риск

В некоторых случаях можно вызвать std::string методы или со строковым литералом или с одним заключенным в кавычки символом. В этих случаях это неэффективно, чтобы вызвать std::string методы со строковым литералом, потому что такие вызовы обеспечивают компилятор, чтобы вычислить длины строковых литералов, который уже известен перед временем выполнения. Поскольку std::string методы часто используются, неэффективные вызовы этих методов могут привести к дорогому и неэффективному коду.

Фиксация

Чтобы устранить эту проблему, вызовите std::string методы при помощи одного заключенных в кавычки символов вместо строкового литерала в надлежащих случаях. Например, вы можете использовать один заключенный в кавычки символ в качестве входа вместо строкового литерала, состоящего из отдельного символа или повторение отдельного символа. Вы можете должны быть использовать различную перегрузку метода, который принимает один заключенный в кавычки символ.

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

Примеры

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

#include <string>
#include <set>
constexpr size_t ONE(){ return 1; }
void foo(std::string& str){
	int pos, count;
	str += "A";
	str += "\0";
	str.find("AA", 0, ONE());
	str.find("A");
	str.find_first_of("A");
	str.find_last_of("A"); 
	str.find_first_not_of("A");
	str.find_last_not_of("A");
	str.replace(0, 1, "A");
	str.rfind("AA", 0,1);
	str.replace(0, count, "AAAAA");
	str.replace(pos, count, "AB", 1);
}

В этом примере, нескольких методах и операторах std::string класс вызывается, чтобы выполнить строковые операции. Для этих вызовов вы уже знаете длину строковых литералов перед временем выполнения программы. Поскольку вход передается как объект строки, компилятор выполняет линейный поиск, чтобы найти его длину, которая избыточна. Polyspace отмечает такой неэффективный вызов строковых операций.

Коррекция – Перегрузки Использования, который Принимает char как Вход

Чтобы устранить эту проблему, используйте один заключенный в кавычки символ вместо строкового литерала. Для методов, таких как replace, перепишите вызов функции и используйте перегрузку, которая принимает char переменные типа, когда вход является отдельным символом.

#include <string>
#include <set>
constexpr size_t ONE(){ return 1; }
void foo(std::string& str){
	int pos, count;
	str += 'A';
	str += '\0';
	str.find('A');
	str.find_first_of('A');
	str.find_last_of('A'); 
	str.find_first_not_of('A');
	str.find_last_not_of('A');
	str.replace(0, 1, 1,'A');//Rewritten call that accepts a single char
	str.rfind('A');
	str.replace(0, count, 5,'A');//Rewritten call that accepts a single char
	str.replace(pos, count, 1,'A');
}

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

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