While profiling a C++ application, I've noticed that the following code:
std::string s;
int i;
dict[s[i]] ++;
yields an invokation of (inline) std::string::_M_leak_hard
, chaining into std::string::_M_mutate
and more (gcc-4.7.3), and going through an insane number of CPU instructions comparing internal state of string, at what should've been a const context and optimized away to a simple memory read.
Am I doing something terribly wrong? That chain of std::string implementation-specific detail burns easily through 50% of the CPU time.
The code you are looking at is indeed the unsharing in the gcc implementation of std::string
. As of why the compiler chose the mutable path for this LHS, the answer is simple: that is how overload resolution. The operator to use is picked by checking the arguments and the object on which the operator is called. In this case, the object is non-const and thus the non-const overload is picked up.
You could try to force picking up the const overload with a minimal change in the code:
std::string s = ..;
int i = ..;
const std::string& r = s;
++dict[r[i]];
Where the main change is creating a const reference to the object to force the use of the const overload of operator[]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With