比较Java循环的性能

来源:互联网 发布:淘宝客服业绩 编辑:程序博客网 时间:2024/05/17 23:38

Java语言中,常用的循环语句有4种。这些循环是编写Java代码必然会涉及到的控制流语句,片段代码如下。

    1. For each 语句

       这个循环式在Java5中引进的,优点是很简洁。

     

[java] view plaincopyprint?
  1. private List<Integer> list = new ArrayList<>();  
  2. for(Integer i : list){  
  3.     // 业务逻辑  
  4. }  
    2. 使用list.size()作为状态

    

[java] view plaincopyprint?
  1. private List<Integer> list = new ArrayList<>();  
  2. for(int j = 0; j < list.size() ; j++){  
  3.     //业务逻辑  
  4. }  
    3. 初始化本地变量size

[java] view plaincopyprint?
  1. private List<Integer> list = new ArrayList<>();  
  2. int size  =  list.size()  
  3. for(int j = 0; j < list.size() ; j++){  
  4.     //  
  5. }  
    4. 初始化计时器的值

[java] view plaincopyprint?
  1. private List<Integer> list = new ArrayList<>();  
  2. for(int j = list.size(); j > size ; j--){  
  3.     //<span style="font-family: 'Segoe UI', 'Lucida Grande', Verdana, Arial;">业务逻辑</span>  
  4. }  

    比较这4种方式的性能,请看下面的程序。

[java] view plaincopyprint?
  1. public class LoopPerformance {  
  2.     private static List<Integer> list = new ArrayList<Integer>(1000000);  
  3.   
  4.   
  5.     static {  
  6.         for (int i = 0; i < 10000000; i++) {  
  7.             list.add(i);  
  8.         }  
  9.     }  
  10.   
  11.     public void testLoopPerformance(){  
  12.         long startTime;  
  13.         long endTime;  
  14.         //style 1  
  15.         startTime = System.nanoTime();  
  16.         for (Integer i : list) {  
  17.             //  
  18.         }  
  19.         endTime = System.nanoTime();  
  20.         System.out.println("For each loop :: " + (endTime - startTime) + " ms");  
  21.   
  22.         //style 2  
  23.         startTime = System.nanoTime();  
  24.         for (int j = 0; j < list.size(); j++) {  
  25.             //  
  26.         }  
  27.         endTime = System.nanoTime();  
  28.         System.out.println("Using collection.size() :: " + (endTime - startTime) + " ms");  
  29.   
  30.         //style 3  
  31.         startTime = System.nanoTime();  
  32.         int size = list.size();  
  33.         for (int j = 0; j < size; j++) {  
  34.             //  
  35.         }  
  36.         endTime = System.nanoTime();  
  37.         System.out.println("Using [int size = list.size(); int j = 0; j < size ; j++] :: " + (endTime - startTime) + " ms");  
  38.   
  39.         //style 4  
  40.         startTime = System.nanoTime();  
  41.         for (int j = list.size(); j > 0; j--) {  
  42.             //System.out.println(j);  
  43.         }  
  44.         endTime = System.nanoTime();  
  45.         System.out.println("Using [int j = list.size(); j > 0 ; j--] :: " + (endTime - startTime) + " ms");  
  46.     }  
  47.     public static void main(String[] args) {  
  48.         new LoopPerformance().testLoopPerformance();  
  49.     }  
  50. }  

输出结果:
For each loop :: 48459306 ms
Using collection.size() :: 13065838 ms
Using [int size = list.size(); int j = 0; j < size ; j++] :: 12495 ms
Using [int j = list.size(); j > 0 ; j--] :: 9371 ms

       显然,style 1 时间消耗最大,随后是style2。而style 3 和tyle 4的性能差别不大,可以考虑这两者是一样的。为什么会有这样的结果呢? 
       style 3 和style 4它们都采用了collection集合的初始值,然后,在循环中用到。唯一的区别在于使用上,一个是作为状态比较,而另一个则作为变量的初始值。style 2使用size()作为循环判断的标准,每次作比较的时,它都会被调用一次。尽管JVM优化了内联调用以及其他优化,但是,多为大量的调用,必然会花费不必要的时间。需要知道,这样编码,在机器上执行的代码语句(字节码)更多。style 4 是最花费性能的,原因是它内部使用循环的迭代iterator 形式。创建interator和调用interator.get() 上花费很多的时间。