根据this question(即OP表示相信并且未得到纠正) - 链式运营商向左增长:
a << b << c << d;
// ==
operator<<( operator<<( operator<<(a, b), c ), d);
为什么会这样?这样做会不会更有效率:
operator<<( operator<<(a, b), operator<<(c, d) );
即,要尽可能地平衡?
当然,编译器可以想出更好的运行时性能吗?
答案 0 :(得分:3)
当您在C ++中重载运算符时,它保留了运算符未超载时的优先级和关联性。
对于移位运算符(<<
和>>
),标准要求:
移位运算符&lt;&lt;和&gt;&gt;从左到右分组。
这意味着必须将a<<b<<c
之类的操作解析为(a<<b)<<c
。
重载运算符会更改为每个操作调用的代码,但对分组没有影响 - 无论a
,b
还是{{c
,int
和{{{{}},分组都是相同的1}}是内置类型(例如,{{1}}),将使用编译器提供的运算符,或者它们是否为将使用重载运算符的某些类类型。处理分组的解析器无论如何都保持相同。
但请注意order of evaluation is independent of precedence or associativity,因此不必然会影响执行速度。
答案 1 :(得分:1)
std::cout
之外,请考虑以下整数算术问题:3 * 5 / 2 * 4
应导致(15 / 2) * 4
,意为28
,但如果拆分,则会产生15 / 8
,意味着1
。即使运营商具有相同的重要性,情况也是如此。修改强>
很容易认为我们可以在核心之间拆分交换操作,例如3 * 5 * 2 * 4
。
现在让我们考虑核心之间通信的唯一方法是通过共享内存。并且平均加载时间比平均CPU运行时间慢一个数量级。仅这一点就意味着在适应1次负载之前需要进行大量的数学运算才有意义。但更糟糕的是:
你可以看到在负载费用的情况下会有多糟糕。让我们看看如果一切都保存在一个核心上就可以完成的优化:
1.2 * 3 * 4 * 5
CPU将先执行3 * 4 * 5
并且只进行1次浮点操作。