java - java for循环中的分支预测

标签 java javafx java-8 branch-prediction

我在 if 条件旁边看到了这条评论:

// branch prediction favors most often used condition

JavaFX 的源代码中SkinBase类。

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;
}

我相信开发者想要解释为什么他写了一个 negate if .

这个优化真的有用吗?

最佳答案

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));
  }
}

因为分支预测本质上会将 if/else 变成适合您的东西(给予或接受)。


This commit证实了这个解释,虽然我不确定他们为什么改变它 - 可能是因为当 isManaged 条件永远不成立时它会产生副作用......

进一步调查,提交指的是 a bug "up to 50% performance regression in Controls benchmarks" (您需要登录才能访问它)。

他们似乎遇到了性能问题,并且在调查时注意到代码中存在错误(与我上面的示例类似)。他们修复了该错误并添加了评论以澄清该修复不会影响性能,这要归功于分支预测。

摘录:

[..] looking at the code, I noticed an error in the case where none of the skin's children are managed. In such a case, minX/Y and maxX/Y would end up being MAX/MIN_VALUE where we really want them to be zero. So this change set fixes that issue. In testing, I saw a small (~1 fps) improvement in performance, so I don't think this change fixes the performance problem. Regardless, the code must be the way it is.

[...] Note that there was a bug in the use of MIN/MAX - those values are not the largest and smallest values for Float and Double (that would have made sense wrt symmetry with the integral types, but it isn't the way they were specified). For doing min/max operations on floating point values you want to use the NEGATIVE/POSITIVE_INFINITY values instead to achieve the results you are looking for.

关于java - java for循环中的分支预测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30370136/

相关文章:

java - 如何使用 Morphia 存储空字段

java - 如何通过Java配置使用Spring Security实现多登录场景?

JavaFX - 获取节点相对于其父节点的坐标

java - 使用带有 Java 8 流的交互式调试器的问题

带有 Function.apply 的 Java 泛型

java - 为什么几个 java.util.List 方法不使用类型参数?

JavaFx:组合框最大宽度

textarea - 如何知道用户在 JavaFX TextArea 中选择了哪个文本字符串

java - 是否可以在java 8流的过滤器方法中执行另一个过程

java - 如何在 jboss 6 上的 HornetMQ 中设置主题