c++ 如何处理 0*(大表达式)
How does c++ handle 0*(large expression)
关于速度,如果我需要计算一个大表达式,比如:
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);
这里记录了一堆这样的位黑客: https://graphics.stanford.edu/~seander/bithacks.html
基准测试并分开,阅读生成的汇编语言,以了解编译器实际上为您(或)做了什么。
switch1
可以是0
也可以是1
,也可以是switch2
如果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(...);
}
你也可以用指向函数的指针做一些聪明的事情:
int guardedFunctionCall(bool switch, int *functionptr(foo), foo arg) {
if(switch) {
return 0;
}
return (*functionptr)(arg);
}
。这接近您在 Java 中懒惰地使用Supplier
评估代码时会做的事情。
或者,由于您使用的是 C++ 而不是 C,您可以做一些更 OO 的操作,并实际使用 C++ 等价物Supplier
: java.util.function.Supplier C++等价物是什么?
if 取决于确切的条件。CPU,编译器,确切的表达式。
如果if
if
成为程序集代码中的条件跳转,并且无法预测条件,则可能会减慢程序的速度。
如果条件无法预测,并且"大表达式"实际上很简单,那么做"乘法方式"可能会更快。
但是,如果表达式计算速度很慢,或者if
可以完美地进行分支预测(或者它不能编译为条件跳转),那么我认为if
方式会更快。
总而言之,您应该尝试这两种解决方案,并检查哪种解决方案更快。
- 警告处理为错误这里有什么问题
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 有人可以帮助我处理正则表达式吗?
- 容器如何处理 lambda 表达式的参数
- c++ 如何处理 0*(大表达式)
- 有什么方法可以通过删除表达式安全地处理两次释放内存?
- 如何对标准::正则表达式进行哈希处理
- 使用多线程处理对象数组 - 无效使用 void 表达式错误
- C++ 正则表达式错误(未处理的异常)
- 用C++处理输出表达式
- 在调车场处理带括号的表达式
- 如何在表达式计算器中处理二进制整数
- 处理对“vector_binary_operation”类中“表达式”的引用,而无需不必要的副本
- 使用正则表达式处理ASCII字符
- 编写c++正则表达式以匹配#include预处理指令
- C++ 如何处理循环中使用的 lambda 表达式for_each返回值
- 在c++ lambda表达式中调用类成员函数失败.处理步骤
- 处理正则表达式字符串时编译崩溃(内存泄漏)
- 我想用正则表达式处理字符串,但如何编写正确的正则表达式
- 函数强制转换中作为复合表达式处理的表达式列表[-fpermissive]