局部变量和常量的性能分析
前兩天群里有人問,下面的代碼1 比代碼2運行時間上慢了100ms,這是問什么?
請看下面的兩個代碼片段:
代碼1
for(int i=0; i<Integer.MAX_VALUE; i++){sum+=i; }代碼2
for(int i=0, len=Integer.MAX_VALUE; i<len; i++){sum+=i; }我本地使用的JDK1.8執行的,但每次執行這兩段的時間基本一樣。
下面代碼是我執行的測試代碼:
代碼3
public class Test {public static void main(String[] args) {test1();test2();}public static int test1() {long start = System.currentTimeMillis();int sum = 0;for (int i = 0; i < Integer.MAX_VALUE; i++) {sum += i;}long end = System.currentTimeMillis();System.out.println(end - start);return sum;}public static int test2() {long start = System.currentTimeMillis();int sum = 0;for (int i = 0, len = Integer.MAX_VALUE; i < len; i++) {sum += i;}long end = System.currentTimeMillis();System.out.println(end - start);return sum;} }發現每次執行時間差不多,不會出現上述的差別的。我使用的JDK1.8??赡軇e的版本的JDK有此問題。
下面我又通過添加JVM編譯模式參數運行程序得到如下結果:
-Xint:全部使用字節碼解釋運行
-Xcomp:全部被編譯成機器碼執行
-Xmixed: 使用混合編譯,jdk1.8默認執行方式
從執行結果我們發現
-Xcomp 和 -Xmixed模式:編譯成本地機器碼后執行的效率是一樣的,沒啥區別
-Xint模式:解釋執行兩個方法執行時間差距大概2秒
為什么-Xint模式下會有2秒的時間差距呢?
代碼1和代碼2的區別
代碼1:在for循環中直接使用常量Integer.MAX_VALUE進行對比。
代碼2:在定義一個len變量賦值為Integer.MAX_VALUE,在for循環中使用len局部變量進行對比。
區別一個引用的是全局常量,一個引用的是局部變量
局部變量存儲在棧的局部變量表中
常量存儲在方法區的常量池中(jdk1.7或之前叫方法區,jdk1.8叫元空間)
下面從字節碼角度分析Test類中的test1方法和test2方法的局部變量表。
從字節碼從11到21之間是for循環體,可以看出19行ldc指令是每次都是從常量池中獲取Integer.MAX_VALUE的值。
字節碼15-25之間是for循環,這個方法,我們可以看到在for循環外面先從常量池中獲取Integer.MAX_VALUE的值賦值給本地變量,for循環體內每次進行比較的是本地變量,也就是局部變量表中的值,而不是每次從常量池獲取變量的值。這就是test2方法比test1方法快的原因。
本人簡書blog地址:http://www.jianshu.com/u/1f0067e24ff8????
點擊這里快速進入簡書
GIT地址:http://git.oschina.net/brucekankan/
點擊這里快速進入GIT
總結
以上是生活随笔為你收集整理的局部变量和常量的性能分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多线程并发下的单例模式
- 下一篇: 使用DelayQueue 和 Futur