Expensive construction of std::string or
std::regex from constant string
A constant std::string or std::regex object is
constructed from constant data, resulting in inefficient code
Description
Polyspace® reports this defect when both of these conditions are true:
You construct an
std::stringorstd::regexobject from constant data, such as a string literal or the output of aconstexprfunction.The
std::stringorstd::regexobject remains constant or unmodified after the construction.
This defect checker does not flag class member variables, and string literals that are function arguments.
Risk
Consider a code block that constructs an std::string or
std::regex object from constant data that remains unmodified after
construction. Every time this code block executes, a new object is constructed without the
same constant data. Repeated construction of such an object with no modification to the
content is inefficient and difficult for you detect. Consider this
code:
#include <string>
constexpr char* getStrPtr() {
return "abcd";
}
void foo(){
std::string s1 = "abcd";
std::regex reg1{"(\\w+)"};
std::string s2 = getStrPtr();
}
int main(){
//...
for(int i = 0; i<10000; ++i)
foo();
}main() invokes the function foo
10000 times in a loop. Each time, the function foo
constructs the objects reg1, s1, s2
from the same constant string literal, resulting in inefficient code. Because such
inefficient code compiles and functions correctly, you might not notice the inefficient
construction of these objects from constant data.Fix
The fix for this defect depends on how you intend to use the constant data.
If you do not need to reuse the constant data, use is directly as temporary literals
If you need to reuse the constant data and you need the functionalities of
std::stringorstd::regexclass, store the constant data in astaticstring object.If you need to reuse the constant data and you do not need the functionalities of or
std::regexclass, store the constant data by using aconstcharacter array or anstd::string_viewobject. Use ofstd::string_viewis supported by C++17 and later.
Consider this code:
constexpr char* getStrPtr() {
return "abcd";
}
void foo(){
static const std::string s1 = getStrPtr();
static const std::regex reg1{"(\\w+)"};
std::string_view s1a{s1};
}
int main(){
//...
for(int i = 0; i<10000; ++i)
foo();
}reg1 and s1 as
static const. Because these are static, they are
constructed only once even if foo is called 10000
times. The std::string_view object s1a shows the
content of s1 and avoids the construction of an
std::string object. By using std::string_view and
static const objects, you avoid unnecessary construction of constant
objects. This method also clarifies that the objects s1 and
s1a represent the same data.Performance improvements might vary based on the compiler, library implementation, and environment that you are using.
Examples
Result Information
| Group: Performance |
| Language: C++ |
| Default: Off |
Command-Line Syntax:
EXPENSIVE_CONSTANT_STD_STRING |
| Impact: Medium |
Version History
Introduced in R2020bSee Also
Topics
- Interpret Bug Finder Results in Polyspace Desktop User Interface
- Interpret Bug Finder Results in Polyspace Access Web Interface (Polyspace Access)
- Address Results in Polyspace User Interface Through Bug Fixes or Justifications
- Address Results in Polyspace Access Through Bug Fixes or Justifications (Polyspace Access)