代码如下:

/* 

* 0.0.0 ~99.9.0 

* 执行次数 100*10*1=1000次 

* 执行时间 812 

*/ 

public void doThing(){ 

for(int i = 0;i<10000;i++) { 

 for(int j = 0;j<1000;j++) { 

 for(int k = 0;k<100;k++) { 

 function(i,j,k); 

 } 

 } 

 } 

} 


/* 

* 0.0.0 ~ 0.9.99 

* 执行次数 1*10*100=1000次 

* 执行时间 703 

*/ 

public void doOpThing(){ 

for(int i = 0;i<100;i++) { 

 for(int j = 0;j<1000;j++) { 

 for(int k = 0;k<10000;k++) { 

 function(i,j,k); 

 } 

 } 

 } 

} 


/* 

* 0.0.0 ~ 0.9.99 

* 执行次数 1*10*100=1000次 

* 执行时间 703 

*/ 

public void doOp2Thing(){ 

int i,j,k; 

for(i = 0;i<100;i++) { 

 for(j = 0;j<1000;j++) { 

 for(k = 0;k<10000;k++) { 

 function(i,j,k); 

 } 

 } 

 } 

} 

其实这道题的目的并不是让你写出优化的方法,而是考你JVM的编译解析原理. 

/ Method descriptor #6 ()V 

 // Stack: 4, Locals: 4 

 public void doThing(); 

 0 iconst_0 --将int型0推送至栈顶 

 1 istore_1 [i] --将栈顶int型数值存入第二个本地变量 

 2 goto 44 --无条件转移 

 5 iconst_0 --将int型0推送至栈顶 

 6 istore_2 [j] --将栈顶int型数值存入第三个本地变量 

 7 goto 34 --无条件转移 

 10 iconst_0 --将int型0推送至栈顶 

 11 istore_3 [k] --将栈顶int型数值存入第四个本地变量 

 12 goto 25 --无条件转移 

 15 aload_0 [this] --将第一个引用类型本地变量推送至栈顶 

 16 iload_1 [i] --将第二个int型本地变量推送至栈顶 

 17 iload_2 [j] --将栈顶int型数值存入第三个本地变量 

 18 iload_3 [k] --将栈顶int型数值存入第四个本地变量 

19 invokevirtual org.yclframework.auth.test.dao.ibatis.Optimize.function(int, int, int) : void [24] –执行方法 

[以上执行过程都是一致的,两个方法] 

 22 iinc 3 1 [k] --将指定int型变量增加指定值,这里是++ 

 25 iload_3 [k] --将第四个int型本地变量推送至栈顶 

 26 bipush 100 --将单字节的常量值(-128~127)推送至栈顶 

 28 if_icmplt 15 --比较栈顶两int型数值大小,当结果小于0时跳转 

 31 iinc 2 1 [j] --将指定int型变量增加指定值,这里是++ 

 34 iload_2 [j] --将栈顶int型数值存入第三个本地变量 

 35 sipush 1000 --将一个短整型常量值(-32768~32767)推送至栈顶 

 38 if_icmplt 10 --比较栈顶两int型数值大小,当结果小于0时跳转 

 41 iinc 1 1 [i] --将指定int型变量增加指定值,这里是++ 

 44 iload_1 [i] --将栈顶int型数值存入第二个本地变量 

 45 sipush 10000 --将一个短整型常量值(-32768~32767)推送至栈顶 

 48 if_icmplt 5 --比较栈顶两int型数值大小,当结果小于0时跳转 

 51 return --方法返回 

 Line numbers: 

 [pc: 0, line: 17] 

 [pc: 5, line: 18] 

 [pc: 10, line: 19] 

 [pc: 15, line: 20] 

 [pc: 22, line: 19] 

 [pc: 31, line: 18] 

 [pc: 41, line: 17] 

 [pc: 51, line: 24] 

 Local variable table: 

 [pc: 0, pc: 52] local: this index: 0 type: org.yclframework.auth.test.dao.ibatis.Optimize 

 [pc: 2, pc: 51] local: i index: 1 type: int 

 [pc: 7, pc: 41] local: j index: 2 type: int 

 [pc: 12, pc: 31] local: k index: 3 type: int


编译成Calss的doThing(),其与doOpThing()唯一不同的是执行顺序,其执行顺序如下:

22 iinc 3 1 [k] 

 25 iload_3 [k] 

 26 sipush 10000 

 29 if_icmplt 15 

 32 iinc 2 1 [j] 

 35 iload_2 [j] 

 36 sipush 1000 

 39 if_icmplt 10 

 42 iinc 1 1 [i] 

 45 iload_1 [i] 

 46 bipush 100 

 48 if_icmplt 5 

51 return


doOpThing()与doOp2Thing()的执行顺序一模一样.
在出入栈操作中,doThing出入栈如下:
变量 出入栈次数 /比较次数
K 100*1000*10000
J 1000*10000
I 10000
在出入栈操作中,doOpThing的出入栈如下:
变量 出入栈次数 /比较次数
K 10000*1000*100
J 1000*100
I 100
其实For循环里面使用的都是局部变量,其变量采用的是本地变量,只初始化一次
接下来都是出入栈和比较的操作,大家可以看到出入栈和比较次数都是相当快的.
采用优化策略却在时间上却提升了10%,虽然是毫妙级别的,但是如果function是一个执行时间很长的程序,那么程序的提升将会很大.