在 Java 中访问 final 局部变量比访问类变量更快吗? [英] Is it faster to access final local variables than class variables in Java?

查看:23
本文介绍了在 Java 中访问 final 局部变量比访问类变量更快吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究一些 Java 原始集合(trovefastutil, hppc) 并且我注意到一个模式,类变量有时被声明为 final 局部变量.例如:

I've been looking at at some of the java primitive collections (trove, fastutil, hppc) and I've noticed a pattern that class variables are sometimes declared as final local variables. For example:

public void forEach(IntIntProcedure p) {
    final boolean[] used = this.used;
    final int[] key = this.key;
    final int[] value = this.value;
    for (int i = 0; i < used.length; i++) {
        if (used[i]) {
          p.apply(key[i],value[i]);
        }
    }
}

我已经做了一些基准测试,看起来这样做时稍微更快,但为什么会这样呢?我试图了解如果将函数的前三行注释掉,Java 会有什么不同.

I've done some benchmarking, and it appears that it is slightly faster when doing this, but why is this the case? I'm trying to understand what Java would do differently if the first three lines of the function were commented out.

注意:这似乎类似于 this question,但那是针对 C++ 的,并没有说明为什么将它们声明为 final.

Note: This seems similiar to this question, but that was for c++ and doesn't address why they are declared final.

推荐答案

final 关键字在这里是一个红鲱鱼.性能差异是因为他们说的是两种不同的东西.

The final keyword is a red herring here. The performance difference comes because they are saying two different things.

public void forEach(IntIntProcedure p) {
  final boolean[] used = this.used;
  for (int i = 0; i < used.length; i++) {
    ...
  }
}

是说,获取一个布尔数组,然后为 那个 数组的每个元素做一些事情."

is saying, "fetch a boolean array, and for each element of that array do something."

如果没有final boolean[] used,函数会说当索引小于当前对象的used字段的当前值的长度时,获取当前对象的 used 字段的当前值,并对索引 i 处的元素进行处理."

Without final boolean[] used, the function is saying "while the index is less than the length of the current value of the used field of the current object, fetch the current value of the used field of the current object and do something with the element at index i."

JIT 可能更容易证明循环绑定不变量以消除过多的绑定检查等,因为它可以更轻松地确定什么会导致 used 的值发生变化.即使忽略多个线程,如果 p.apply 可以改变 used 的值,那么 JIT 不能消除边界检查或做其他有用的优化.

The JIT might have a much easier time proving loop bound invariants to eliminate excess bound checks and so on because it can much more easily determine what would cause the value of used to change. Even ignoring multiple threads, if p.apply could change the value of used then the JIT can't eliminate bounds checks or do other useful optimizations.

这篇关于在 Java 中访问 final 局部变量比访问类变量更快吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆