C++ c++;句柄0*(大表达式)
关于速度,如果我需要计算一个大表达式,可以说:C++ c++;句柄0*(大表达式),c++,if-statement,switch-statement,expression,C++,If Statement,Switch Statement,Expression,关于速度,如果我需要计算一个大表达式,可以说: switch1*(large expression 1)+switch2*(large expression 2) 根据我的输入,switch1可以是0或1,也可以是switch2。什么是最快的C++,做一个if语句或写下来,上面的? ,所以,本质上你是在问“强”短路评价,你问C++除了算术表达式之外是否也做算术表达式。 证明否定是困难的,但据我所知,C++只对逻辑表达式进行短路评价,因此算术表达式没有等价性。此外,如果算术表达式以短路方式求值,
switch1*(large expression 1)+switch2*(large expression 2)
根据我的输入,
switch1
可以是0
或1
,也可以是switch2
。什么是最快的C++,做一个if语句或写下来,上面的? ,所以,本质上你是在问“强”短路评价<强>,你问C++除了算术表达式之外是否也做算术表达式。
证明否定是困难的,但据我所知,C++只对逻辑表达式进行短路评价,因此算术表达式没有等价性。此外,如果算术表达式以短路方式求值,我可以想到很多代码会严重中断,因此我认为这是不可能的。
理论上,编译器可以生成代码,以避免计算表达式,如果它能显示出没有副作用的话。但在实践中,不太可能添加代码来检查值是否为零,因为它没有理由认为它将为零 另一方面,逻辑操作(代码> > <代码/代码>和代码> &代码>保证了C++中的短路。所以你应该使用它们result = 0;
if(switch1) {
result += large_expresion_1();
}
if(switch2)
result += large_expression2();
}
但是,如果您正在优化“大表达式”,请务必检查计算它们是否真的更快,然后以无分支的方式添加它们。例如
result = ((-(uint64_t)(switch1)) & large_expression_1) + ((-(uint64_t)(switch2)) & large_expression_2);
这里记录了大量此类比特黑客:
除了基准测试之外,阅读生成的汇编语言以了解编译器实际上为您(或为您)做了什么
开关1
可以是0
或1
,开关2也可以是
如果switch1
和switch2
实际上只能有0
或1
的值,那么它们最好是布尔值而不是整数
使用布尔开关,您的语句变为:
result = (switch1 ? (large expression 1) : 0)
+ (switch2 ? (large expression 2) : 0)
在这种情况下,即使不使用表达式的结果,也会计算表达式。避免浪费计算的一个简单明了的方法是:
result = 0;
if(switch1) {
result += large expression 1;
}
if(switch2) {
result += large expression 2;
}
您可以通过提取方法来整理这些内容,将开关传递到这些方法中:
result = guardedLargeExpression1(switch1, otherparams1)
+ guardedLargeExpression2(switch2, otherparams2);
。。。与
int guardedLargeExpression1(bool switch, foo params) {
if(switch) {
return 0;
}
return large expression(...);
}
你也可以做一些聪明的事情:
。。。这正接近您在Java中使用供应商
惰性地评估代码时所做的事情
或者,因为你在C++中,而不是C,你可以做更多的OO,并且实际上使用C++的等价于<代码>供应商< /> >:
< P>如果要依赖于具体的条件。CPU,编译器,精确表达式
如果if
成为汇编代码中的条件跳转,并且无法预测该条件,则if
会减慢程序的速度
如果无法预测条件,并且“大表达式”实际上很简单,那么使用“乘法”可能会更快
但是,如果表达式的计算速度很慢,或者if
可以很好地进行分支预测(或者它没有编译成条件跳转),那么我认为if
方法会更快
总之,您应该尝试两种解决方案,并检查哪一种更快。请提供一个解决方案,您可以在Godbolt上自己检查。如果您是大型Expression包含函数调用,编译器无法确定它们是否没有副作用,则不会对它们进行优化。如果其中任何一个开关在编译时不是常量0值,也不会对整个表达式进行优化。看起来像是过早优化。首先测量,然后优化。这取决于表达式是什么。例如,编译器能告诉我们它们没有副作用吗?
int guardedFunctionCall(bool switch, int *functionptr(foo), foo arg) {
if(switch) {
return 0;
}
return (*functionptr)(arg);
}