【发布时间】:2020-09-16 18:54:51
【问题描述】:
在Quick Bench 上检查的这个 google-benchmark 代码表明,string::empty() 的运行速度比与空字符串文字相比要快得多。但是,创建"" 的名称字符串实际上会使编译器优化检查:
bool compareWithNamedConst(const std::string& target) {
const std::string emptyString = "";
return emptyString == target;
}
bool compareWithLiteral(const std::string& target) {
return "" == target;
}
bool compareWithRvalue(const std::string& target) {
return std::string{""} == target;
}
bool checkForEmpty(const std::string& target) {
return target.empty();
}
每个调用的性能如下所示:
如您所见,与所有其他选项相比,与 "" 的比较速度非常慢。我想知道为什么会这样?它一定与未在const char* 上应用 SSO 有某种关系,因为测试:
bool compareWithLiteral(const std::string& target) {
return "test with a longer string not optimized" == target;
}
bool compareWithRvalue(const std::string& target) {
return std::string{"test with a longer string not optimized"} == target;
}
与文字比较的结果实际上更快:
我发现检查字符串是否为空,最容易阅读的语法是"" == myVariable,因为它清楚地表明myVariable 是std::string,没有不必要的混乱。为什么我们不能像其他所有情况一样对其进行优化?
【问题讨论】:
-
您在运行这些示例时采用了哪种优化方式?
-
-O3关于 gcc 和 clang -
compareWithLiteral 是比较不同类型对象的唯一情况。我猜这就是根本原因。我不太确定允许编译器“优化”隐式转换。
-
fwiw,使用
lenght() == 0代替empty()也是一个很好的提示,它是一个字符串,不需要使用字符串文字,虽然这更易读当然是意见跨度> -
似乎
"" == std::string()调用strcmp,而std::string() == std::string()调用memcmp。我的猜测是,提前知道字符串的大小可以让std::string::operator==(std::string)立即比较大小。 this compare 与 this compare