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