gon*_*ard 8 java javafx java-8 branch-prediction
我在if条件旁边看到了这条评论:
// branch prediction favors most often used condition
protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
double minX = 0;
double maxX = 0;
boolean firstManagedChild = true;
for (int i = 0; i < children.size(); i++) {
Node node = children.get(i);
if (node.isManaged()) {
final double x = node.getLayoutBounds().getMinX() + node.getLayoutX();
if (!firstManagedChild) { // branch prediction favors most often used condition
minX = Math.min(minX, x);
maxX = Math.max(maxX, x + node.minWidth(-1));
} else {
minX = x;
maxX = x + node.minWidth(-1);
firstManagedChild = false;
}
}
}
double minWidth = maxX - minX;
return leftInset + minWidth + rightInset;
}
Run Code Online (Sandbox Code Playgroud)
我相信开发人员想要解释为什么他写了否定if.
这个优化真的有用吗?
ass*_*ias 12
JavaFX团队的人员非常注重性能,所以他们肯定知道切换if和else对分支预测没有实质性影响.
我想这表明重构没有显着的性能提升,因为:
double minX = Double.MAX_VALUE;
double maxX = Double.MIN_VALUE;
for (int i = 0; i < children.size(); i++) {
Node node = children.get(i);
if (node.isManaged()) {
final double x = node.getLayoutBounds().getMinX() + node.getLayoutX();
minX = Math.min(minX, x);
maxX = Math.max(maxX, x + node.minWidth(-1));
}
}
Run Code Online (Sandbox Code Playgroud)
因为分支预测基本上会将if/else变为类似的东西(给予或接受).
这个提交确认了这个解释,虽然我不确定他们为什么改变它 - 可能是因为当isManaged条件从来没有时它有副作用...
进一步调查,提交引用了一个错误"控件基准测试中高达50%的性能回归"(您需要登录才能访问它).
看起来他们遇到了性能问题,而调查时发现代码中有一个错误(类似于我上面的例子).他们修复了这个bug并添加了一条注释,以澄清该修复程序不会影响性能,这要归功于分支预测.
摘录:
[..]查看代码,我注意到在没有管理皮肤的孩子的情况下出现错误.在这种情况下,minX/Y和maxX/Y最终将为MAX/MIN_VALUE,我们真的希望它们为零.因此,此更改集修复了该问题.在测试中,我看到了一个小的(~1 fps)性能改进,所以我不认为这个改变可以解决性能问题.无论如何,代码必须是它的方式.
[...]请注意,使用MIN/MAX时存在一个错误 - 这些值不是Float和Double的最大值和最小值(这对于整数类型来说是对称的,但它不是他们被指定的方式).要对浮点值执行最小/最大操作,您需要使用NEGATIVE/POSITIVE_INFINITY值来实现您要查找的结果.
| 归档时间: |
|
| 查看次数: |
978 次 |
| 最近记录: |