java - int 上的余数运算符导致 java.util.Objects.requireNonNull?

标签 java performance modulo primitive-types null-check

我试图从一些内部方法中获得尽可能多的性能。

Java代码是:

List<DirectoryTaxonomyWriter> writers = Lists.newArrayList();
private final int taxos = 4;

[...]

@Override
public int getParent(final int globalOrdinal) throws IOException {
    final int bin = globalOrdinal % this.taxos;
    final int ordinalInBin = globalOrdinal / this.taxos;
    return this.writers.get(bin).getParent(ordinalInBin) * this.taxos + bin; //global parent
}

在我的分析器中,我看到 java.util.Objects.requireNonNull 中有 1% 的 CPU 开销。 ,但我什至不这么叫。在检查字节码时,我看到了这个:
 public getParent(I)I throws java/io/IOException 
   L0
    LINENUMBER 70 L0
    ILOAD 1
    ALOAD 0
    INVOKESTATIC java/util/Objects.requireNonNull (Ljava/lang/Object;)Ljava/lang/Object;
    POP
    BIPUSH 8
    IREM
    ISTORE 2

所以编译器会生成这个(没用的?)检查。我研究原语,它不能是 null无论如何,为什么编译器会生成这一行?它是一个错误吗?还是“正常”行为?

(我可能会使用位掩码,但我只是好奇)

[更新]
  • 运营商似乎与它无关(见下面的答案)
  • 使用 eclipse 编译器(4.10 版)我得到了更合理的结果:

  • public getParent(I)I throws java/io/IOException
    L0
    第 77 行 L0
    加载 1
    ICONST_4
    IREM
    存储 2
    L1
    LINENUMBER 78 L

    所以这更合乎逻辑。

    最佳答案

    为什么不?

    假设

    class C {
        private final int taxos = 4;
    
        public int test() {
            final int a = 7;
            final int b = this.taxos;
            return a % b;
        }
    }
    

    c.test() 这样的电话在哪里 c被声明为 C必须抛出cnull .你的方法相当于
        public int test() {
            return 3; // `7 % 4`
        }
    

    因为您只使用常量。与 test由于是非静态的,因此必须进行检查。通常,当访问字段或调用非静态方法时,它会隐式完成,但您不这样做。所以需要明确的检查。一种可能是调用 Objects.requireNonNull .

    字节码

    不要忘记字节码基本上与性能无关。 javac的任务是生成一些执行与您的源代码相对应的字节码。这并不是为了做任何优化,因为优化后的代码通常更长更难分析,而字节码实际上是优化 JIT 编译器的源代码。所以javac预计会保持简单......

    表现

    In my profiler I saw there is 1% CPU spend in java.util.Objects.requireNonNull



    我会先责怪分析器。分析 Java 非常困难,您永远无法期待完美的结果。

    您可能应该尝试将方法设为静态。你当然应该阅读 this article about null checks .

    关于java - int 上的余数运算符导致 java.util.Objects.requireNonNull?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60041522/

    相关文章:

    java - 如何使用 spring MVC 的 <mvc :resources> tag in a java application context?

    类实例与局部(numpy)变量的 Python 性能

    java - 如果(计数%2==1)?

    java - 帮助尝试理解圆形阵列中的模运算

    python - tkinter 中字符和事件处理的 % 运算符

    java - Maven Eclipse 调试 "JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510)"

    java - hql 一对多/多对一选择

    java - 使用 RestTemplate.postForEntity 时总是在 ResponseEntity 中得到空响应

    java - 为什么 Java 使用包含 X 的外部变量的函数比直接使用 X 更快?

    mysql简单查询花费较长时间