在分析C ++应用程序时,我注意到以下代码:
std::string s;
int i;
dict[s[i]] ++;
产生(内联)std::string::_M_leak_hard
的调用,链接到std::string::_M_mutate
和更多(gcc-4.7.3),并通过疯狂数量的CPU指令比较字符串的内部状态,在什么应该是一个const上下文,并优化到一个简单的内存读取。
我做错了什么吗? std :: string特定于实现的细节链很容易在50%的CPU时间内烧掉。
答案 0 :(得分:6)
您正在查看的代码确实是std::string
的gcc实现中的取消共享。至于为什么编译器选择了这个LHS的可变路径,答案很简单:那就是重载决策。通过检查参数和调用运算符的对象来选择要使用的运算符。在这种情况下,对象是非const的,因此拾取非const重载。
您可以尝试通过代码中的最小更改来强制获取const重载:
std::string s = ..;
int i = ..;
const std::string& r = s;
++dict[r[i]];
主要更改是创建对象的const引用以强制使用operator[]