Ada*_*adi 5 c++ gcc clang c++14
在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();
}
Run Code Online (Sandbox Code Playgroud)
每个调用的性能如下所示:

正如您所看到的,与""所有其他选项相比,比较速度非常慢。我想知道为什么会这样?它必须以某种方式与未应用 SSO 相关const char*,作为测试:
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;
}
Run Code Online (Sandbox Code Playgroud)
结果与文字相比实际上更快:

我发现,检查字符串空虚,最简单的语法来读是"" == myVariable因为它清楚地表明,myVariable是一个std::string没有unneccesary混乱。为什么我们不能像所有其他情况一样对其进行优化?
对于空性检查,如果您真的喜欢文字语法,您可以通过using namespace std::string_literals;, 并替换""为 来帮助您的编译器""s。在这种情况下compareWithLiteral,compareWithRvalue和checkForEmpty本质上是相同的,因为operator==Betweenconst std::string&通常会在内容之前检查大小,而 的大小""s是微不足道的。
bool compareWithLiteral(const std::string& target) {
using namespace std::string_literals;
return ""s == target;
}
Run Code Online (Sandbox Code Playgroud)
对于不属于 SSO 的字符串,您应该尝试使用std::string_view和 its operator""sv,即使不幸的是仅从 C++17 开始可用。升压有boost::string_view. 没有为编译时创建提供用户字符串文字(这是必需的,因为测试字符串长度将在二进制文件中硬编码),但您可以轻松定义一个:
#include <boost/utility/string_view.hpp>
constexpr auto operator""_sv(const char* str, std::size_t len) noexcept {
return boost::basic_string_view<char>{str, len};
}
bool compareWithLiteral(const std::string& target) {
return "test with a longer string not optimized"_sv == target;
}
Run Code Online (Sandbox Code Playgroud)
该版本的运行速度比您的版本快得多compareWithLiteral,至少在target大小不同时是这样。