Java字节码iconst_0 iadd序列

发布于 2024-08-22 05:04:12 字数 1178 浏览 11 评论 0原文

这是对三元运算符的有趣测试:

public int so( final int a ) {
    int r = (int) System.currentTimeMillis();
    r += a == 2 ? 1 : 0;
    return r;
}

这是生成的字节码:

public int doIt(int);
  Code:
   0:   invokestatic    #2; //Method java/lang/System.currentTimeMillis:()J
   3:   l2i
   4:   istore_2
   5:   iload_2
   6:   iload_1
   7:   iconst_2
   8:   if_icmpne       15
   11:  iconst_1
   12:  goto    16
   15:  iconst_0
   16:  iadd
   17:  istore_2
   18:  iload_2
   19:  ireturn

我有点惊讶地发现它没有删除“+ 0”的“else”情况。我更期待这个:

public int doIt(int);
  Code:
   0:   invokestatic    #2; //Method java/lang/System.currentTimeMillis:()J
   3:   l2i
   4:   istore_2
   5:   iload_1
   6:   iconst_2
   7:   if_icmpne       13
   10:  iinc    2, 1
   13:  iload_2
   14:  ireturn

所以我的问题来了:规范是否强制要求:

goto ...
iconst_0

序列,因为我使用了三元运算符,或者这只是一个编译器的东西?

显然这个问题与编写 'r += ... 的相关性无关? 1:0'。但我很惊讶,因为在其他情况下编译器会进行相当多的优化,而在这里它没有进行任何优化。

生成选项 2 的 Java 编译器仍然是有效的 Java 编译器吗(以防万一我没有搞砸我的示例,但要点是:在生成的代码中存在不必要的 0 和不必要的 goto,编译器删除它仍然会是一个有效的 Java 编译器吗?是一个有效的 .java 编译器)?

Here's a test for fun with the ternary operator:

public int so( final int a ) {
    int r = (int) System.currentTimeMillis();
    r += a == 2 ? 1 : 0;
    return r;
}

Here's the bytecode produced:

public int doIt(int);
  Code:
   0:   invokestatic    #2; //Method java/lang/System.currentTimeMillis:()J
   3:   l2i
   4:   istore_2
   5:   iload_2
   6:   iload_1
   7:   iconst_2
   8:   if_icmpne       15
   11:  iconst_1
   12:  goto    16
   15:  iconst_0
   16:  iadd
   17:  istore_2
   18:  iload_2
   19:  ireturn

I was a bit surprised to see that it didn't remove the 'else' case for the '+ 0'. I was more expecting this:

public int doIt(int);
  Code:
   0:   invokestatic    #2; //Method java/lang/System.currentTimeMillis:()J
   3:   l2i
   4:   istore_2
   5:   iload_1
   6:   iconst_2
   7:   if_icmpne       13
   10:  iinc    2, 1
   13:  iload_2
   14:  ireturn

So here comes my question: does the specs mandates the:

goto ...
iconst_0

sequence because I used the ternary operator, or is this just a compiler thinggy?

Obviously this question is not about the relevancy of writing 'r += ... ? 1 : 0'. But I'm surprised because in other cases the compiler does quite some optimization while here it's not doing any optimization.

Would a Java compiler producing option 2 still be a valid Java compiler (in case I didn't screw my example, but the point is: there's a needless addition of 0 and a needless goto in the code produced, would a compiler removing this still be a valid .java compiler)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

柠北森屋 2024-08-29 05:04:12

需要记住的一件事是,javac(Java 源代码到字节码编译器)不是优化编译器。事实上,它的代码生成相对简单,并且只生成任何给定源代码的最直接的字节码实现。

这完全是设计使然。这样,负责所有实际优化的 JVM 就拥有最大量的可用信息来做出决策。在这种特殊情况下,这些信息如何使 JIT 编译器受益可能并不明显,但由于 HotSpot 所做的优化的性质,每一条信息都可以提供帮助。

例如,可能有一些智能模式匹配可以识别常见的代码片段并以高度优化的版本实现它们。现在,如果 javac 也尝试进行一些优化,那么这些模式可能更难检测。

One thing to keep in mind is that javac (the Java Source code to byte code compiler) is not an optimizing compiler. In fact it is relatively simple in its code generation and only produces the most straight-forward byte-code implementation of any given source code.

That is entirely by design. This way the JVM, which is in charge of all the real optimizations, has the maximum amount of information available on which to base its decisions. In this particular case it might not be obvious how that information can benefit the JIT compiler, but due to the nature of optimizations done by HotSpot for example, every bit of information can help.

For example there might be some smart pattern matching that recognizes common pieces of code and implements them in a highly optimized version. Now if javac tried to do some optimization as well, then those patterns could be much harder to detect.

嘿嘿嘿 2024-08-29 05:04:12

Sun 的 Javac 本身不做任何优化,因为它们留给了 HotSpot VM。因此它产生第一个字节码。

第二个字节码列表与第一个字节码列表一样有效。所以理论上其他一些 Java 编译器也可以产生这样的结果。

如果没有 JIT 的虚拟机(例如 Android 设备)需要这种优化,可以使用 Proguard 等工具在字节码级别进行优化。

Sun's Javac itself does not do any optimizations as they are left for the HotSpot VM. Thus it produces the first bytecode.

The second bytecode listing is as valid as the first one. So in theory some other Java compiler could produce that.

If that kind of optimizations are needed for VMs that does not have JIT (for example Android devices), there are tools like Proguard that do optimizations on bytecode level.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文