gpt4 book ai didi

java - 编译器(或 JVM)会知道优化这段代码吗?我该如何检查?

转载 作者:行者123 更新时间:2023-11-30 06:21:22 24 4
gpt4 key购买 nike

假设我有这门课

Util
{
public static void doSomething()
{
if (FLAG) foo();
else bar();
}

public static void foo() { /* do something */ }
public static void bar() { /* do something else */ }

public static final boolean FLAG = computeFlag();
private static boolean computeFlag() { /* do some computation during init time*/ }
}

FLAG 显然永远不会改变。假设 Util.doSomething()大量使用(并且在许多关键的地方,性能很重要)。Java 编译器或 JVM 是否足够智能以缓存 doSomething 的主体,以便代码不必重新评估 FLAG 或不必执行分支重新上课?

我该如何检查?

谢谢

最佳答案

这可能取决于您使用的 JVM。对于 Oracle Hotspot JVM,您可以使用

检查生成的机器代码
java -server -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly your.MainClass

前提是您在库路径中有必要的 native 库(documentation 提到了您可以获得此类二进制文件的位置)。

运行类:

public class DecompileTest {

public static void doSomething() {
if (FLAG)
foo();
else
bar();
}

static int fooCount;

public static void foo() {
fooCount++;
}

public static void bar() {
fooCount--;
}

public static final boolean FLAG = computeFlag();

private static boolean computeFlag() {
System.out.println("Shall I set the flag? (y/n)");
try {
return System.in.read() == 'y';
} catch (IOException e) {
throw new RuntimeException(e);
}
}

public static void main(String[] args) {
for (int i = 0; i < 1000000; i++) {
doSomething();
}
System.out.println(fooCount);
}
}

java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) Server VM (build 23.21-b01, mixed mode)

在我的 Intel cpu 上产生了一个冗长的 disassabmly,其中的相关部分是这样的:

Decoding compiled method 0x009ca408:
Code:
[Entry Point]
[Verified Entry Point]
[Constants]
# {method} 'doSomething' '()V' in 'stackoverflow/DecompileTest'
# [sp+0x10] (sp of caller)
0x009ca500: sub $0xc,%esp
0x009ca506: mov %ebp,0x8(%esp) ;*synchronization entry
; - stackoverflow.DecompileTest::doSomething@-1 (line 8)
0x009ca50a: mov $0x295dc208,%ebx ; {oop(a 'java/lang/Class' = 'stackoverflow/DecompileTest')}
0x009ca50f: incl 0x70(%ebx) ;*putstatic fooCount
; - stackoverflow.DecompileTest::foo@5 (line 17)
; - stackoverflow.DecompileTest::doSomething@6 (line 9)
0x009ca512: add $0x8,%esp
0x009ca515: pop %ebp
0x009ca516: test %eax,0x950000 ; {poll_return}
0x009ca51c: ret
0x009ca51d: hlt
0x009ca51e: hlt
0x009ca51f: hlt
[Exception Handler]
[Stub Code]
0x009ca520: jmp 0x009c78c0 ; {no_reloc}
[Deopt Handler Code]
0x009ca525: push $0x9ca525 ; {section_word}
0x009ca52a: jmp 0x009ae280 ; {runtime_call}
0x009ca52f: hlt

即同时测试FLAG和调用 bar()已作为死代码被删除,foo 的方法体内联。

关于java - 编译器(或 JVM)会知道优化这段代码吗?我该如何检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20621005/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com