我们知道有人说 Java JIT 比 C++ 快。 我想利用 JIT 并在运行时代码中删除一些指令。
这是我试过的示例代码:
/**
* Created by kadirbasol on 4/6/14.
*/
public class RemoveJump {
public final boolean test;
private static RemoveJump instance = new RemoveJump();
public static final RemoveJump getInstance() {
return instance;
}
private RemoveJump() {
//set the test on the constructor once and
//remove this if statement forever from testLoop
test = false;
}
public final long getData() {
return 1000000000;
}
public final void testLoop() {
long l = System.currentTimeMillis();
int ppp = 0;
long count = System.currentTimeMillis();
final long data = getData();
//this loop should be removed from function because
//RemoveJump set test to false and modified testLoop function
for (int i = 0; i < data ; i++) {
if(test) {
ppp++;
}
if(test) {
ppp++;
}
if(test) {
ppp++;
}
if(test) {
ppp++;
}
if(test) {
ppp++;
}
}
long lastTime = System.currentTimeMillis() - l;
System.out.println(lastTime);
System.out.println(ppp);
}
public static void main(String[] args) {
RemoveJump.getInstance().testLoop();
}
}
代码中有5条if语句。 是否可以在函数中删除这 5 个检查 if 语句? 构造函数将设置最终 boolean 变量一次并删除跳转。 Constructor会修改testLoop函数。
但是我试过的代码没有效果。 JIT 不是修改代码? 为什么 ? 如果不是,我们可以在构造函数上修改 JVM 函数吗? 我听说了http://asm.ow2.org , 用于生成或修改 JVM 的 asm java 库。
最佳答案
事实上,JIT 消除了循环中test
字段的检查。尽管当 data
的类型与循环索引 i
的类型不同时,JIT 似乎不够聪明,无法丢弃循环本身:
0x000000000222f570: inc %ebx ; OopMap{rbp=Oop off=178}
;*goto
; - RemoveJump::testLoop@82 (line 28)
0x000000000222f572: test %eax,-0x20ff578(%rip) # 0x0000000000130000
;*iload
; - RemoveJump::testLoop@20 (line 28)
; {poll}
0x000000000222f578: movslq %ebx,%r10
0x000000000222f57b: cmp %r14,%r10
0x000000000222f57e: jl 0x000000000222f570
如果将 getData()
更改为返回 int
,优化将起作用,并且在结果集合中根本没有循环。
但是你的测试用例不会显示优化效果,因为循环开始以解释器模式执行,在执行中间被编译(同时在循环内),所以即使在编译之后执行仍然在循环内.但是,如果多次调用 testLoop()
,您会发现该方法的进一步调用将立即打印结果,而无需经过循环:
for (int i = 1; i <= 5; i++) {
System.out.println("Run #" + i);
RemoveJump.getInstance().testLoop();
}
Run #1
1897
0
Run #2
1895
0
Run #3
0
0
Run #4
0
0
Run #5
0
0
关于java - 是否可以在 java jit 上删除带有 final boolean 值的跳转?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22890760/