Ale*_*exV 8 c++ string compiler-optimization c++14
我最近发现了类似于以下几行的内容:
#include <string>
// test if the extension is either .bar or .foo
bool test_extension(const std::string& ext) {
return ext == ".bar" || ".foo";
// it obviously should be
// return ext == ".bar" || ext == ".foo";
}
Run Code Online (Sandbox Code Playgroud)
该功能显然没有按照评论的建议去做。但这不是重点。请注意,这不是Can you use 2 or more OR conditions in an if statement? 因为我完全知道您将如何正确编写函数!
我开始想知道编译器会如何处理这个片段。我的第一个直觉是这将被编译为return true;
基本上。将示例插入到Godbolt 中,表明 GCC 9.2 和 clang 9 都没有通过优化进行这种优化-O2
。
但是,将代码更改为1
#include <string>
using namespace std::string_literals;
bool test_extension(const std::string& ext) {
return ext == ".bar"s || ".foo";
}
Run Code Online (Sandbox Code Playgroud)
似乎可以解决问题,因为程序集现在本质上是:
mov eax, 1
ret
Run Code Online (Sandbox Code Playgroud)
所以我的核心问题是:我是否遗漏了什么不允许编译器对第一个片段进行相同的优化?
1随着".foo"s
这甚至不会编译,因为编译器不希望将转换std::string
到bool
;-)
编辑
以下代码段也被“正确”优化为return true;
:
#include <string>
bool test_extension(const std::string& ext) {
return ".foo" || ext == ".bar";
}
Run Code Online (Sandbox Code Playgroud)
这会让你更加困惑:如果我们创建一个自定义 char 类型MyCharT
并使用它来进行我们自己的自定义,会发生什么std::basic_string
?
#include <string>
struct MyCharT {
char c;
bool operator==(const MyCharT& rhs) const {
return c == rhs.c;
}
bool operator<(const MyCharT& rhs) const {
return c < rhs.c;
}
};
typedef std::basic_string<MyCharT> my_string;
bool test_extension_custom(const my_string& ext) {
const MyCharT c[] = {'.','b','a','r', '\0'};
return ext == c || ".foo";
}
// Here's a similar implementation using regular
// std::string, for comparison
bool test_extension(const std::string& ext) {
const char c[] = ".bar";
return ext == c || ".foo";
}
Run Code Online (Sandbox Code Playgroud)
当然,自定义类型不能比普通类型更容易优化char
,对吗?
这是最终的组装结果:
#include <string>
struct MyCharT {
char c;
bool operator==(const MyCharT& rhs) const {
return c == rhs.c;
}
bool operator<(const MyCharT& rhs) const {
return c < rhs.c;
}
};
typedef std::basic_string<MyCharT> my_string;
bool test_extension_custom(const my_string& ext) {
const MyCharT c[] = {'.','b','a','r', '\0'};
return ext == c || ".foo";
}
// Here's a similar implementation using regular
// std::string, for comparison
bool test_extension(const std::string& ext) {
const char c[] = ".bar";
return ext == c || ".foo";
}
Run Code Online (Sandbox Code Playgroud)
那么,我的“自定义”字符串类型和 之间有什么区别std::string
?
至少在 GCC 上,小字符串优化实际上被编译成 libstdc++ 的二进制文件。这意味着,在编译函数期间,编译器无法访问此实现,因此它无法知道是否有任何副作用。因此,它无法优化对compare(char const*)
away 的调用。我们的“自定义”类没有这个问题,因为 SSO 仅针对普通std::string
.
顺便说一句,如果您使用 进行编译-std=c++2a
,编译器会对其进行优化。不幸的是,我对 C++ 20 还不够了解,还不知道哪些变化使这成为可能。
归档时间: |
|
查看次数: |
205 次 |
最近记录: |