正如我们所知,有些人说 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 语句?
构造函数将设置一次最终布尔变量并删除跳转。
构造函数将修改testLoop函数。
但我尝试的代码没有效果。
JIT不是修改代码吗?
为什么 ?
如果没有,我们可以修改构造函数上的 JVM 函数吗?
我听说http://asm.ow2.org http://asm.ow2.org、asm java库,用于生成或修改JVM。
事实上,JIT消除的检查test
循环中的字段。尽管 JIT 似乎不够聪明,无法在类型为data
与循环索引的类型不同i
:
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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)