cpp*_*ner 1 c++ optimization enums switch-statement c++14
我得打电话f(0)和f(1).
参数(0和1)仅用于switch-case.
如何尽可能强制/指导编译器优化开关盒(从"昂贵"到"便宜"版本)?
从godbolt演示开始,switch-case没有经过优化.
示例:昂贵
int f(int n) {
switch(n) {
case 0: {
return 5;
};break;
case 1: {
return 10;
};break;
}
return 15;
}
int main(){
f(0);
}
Run Code Online (Sandbox Code Playgroud)
示例:便宜(我的梦想)
int f0(){
return 5;
}
int f1(){
return 10;
}
int main(){
f0();
}
Run Code Online (Sandbox Code Playgroud)
更多信息 :-
在实际情况中,不仅仅是0和1 - 它们是枚举类.
该参数在用户方面总是不变的,例如f(CALLBACK_BEGIN),f(CALLBACK_END).
为什么我不能只是f0()/ f1()?
我想将它组合成一个函数,因为我有时想要创建一个传递函数.如果我可以编码它,它更容易维护: -
int g(int n){ .... }
int f(int n){ return g(n); }
Run Code Online (Sandbox Code Playgroud)
它比以下更容易维护: -
int g0(){ .... } int g1(){ .... }
int f0(){ return g0(); }
int f1(){ return g1(); }
Run Code Online (Sandbox Code Playgroud)
我也更喜欢避免模板,所以我不能在优化模板替换开关时使用解决方案.我的理由是: -
.cpp,所以我必须将它间接到另一个非模板函数.过早优化?
就我而言,它被称为每秒60*10000 +次.
编辑
我误解了godbolt演示的结果.它实际上是优化的.
(感谢MM和Benoît指出它.)
EDIT2
收到两个很好的答案后,我测试了它,发现Visual C++非常聪明.
它可以优化的东西: -
int f(int p1,int p2){
if(p1==0 && p2==1){ //zero cost
}
}
f(0,1); //inside main
Run Code Online (Sandbox Code Playgroud)
在实际情况中,有3-5层功能间接,但Visual C++仍然可以找到!
结果与类似的帖子一致:循环中的常量条件:编译器优化
一个简单的解决方案是制作您的功能constexpr,这可以大大简化优化.
// v--- that
constexpr int f(int n) {
switch(n) {
case 0: {
return 5;
};break;
case 1: {
return 10;
};break;
}
return 15;
}
Run Code Online (Sandbox Code Playgroud)
这使得函数在编译时可调用.如果传递constexpr值的参数,则编译过程中编译器可以执行该函数.由于您将枚举值作为参数传递,因此很可能在编译时执行该函数.
如果您的繁重函数需要一些运行时值,请尝试分解可以标记为constexpr的部分,并且可能使用模板(它们确实有助于使代码更快!)
constexpr int const_part_of_f(int n) {
switch(n) {
case 0: {
return 5;
};break;
case 1: {
return 10;
};break;
}
}
template<int n>
int f() {
if (get_runtime_value()) {
// Since `n` is a compile time constant, the result of `const_part_of_f` is
// evaluated at compile time, even if `f` is not a constexpr function.
return const_part_of_f(n)
}
return 15;
}
Run Code Online (Sandbox Code Playgroud)
如果您真的想帮助优化器,请避免过多的内存分配.例如,如果需要在编译时已知的特定大小的数组,请使用std::array而不是std::vector.
正如其他用户所指出的,二进制膨胀是为了初始化iostream全局变量.然而,这并不否认constexpr函数更容易被编译器优化的事实.
| 归档时间: |
|
| 查看次数: |
287 次 |
| 最近记录: |