zoukankan      html  css  js  c++  java
  • Java中迭代列表中数据时几种循环写法的效率比较

    Java中经常会用到迭代列表数据的情况,本文针对几种常用的写法进行效率比较。虽然网上已经有了类似的文章,但是对他们的结论并不认同。

    常见的实现方法:

    1.for循环:

    1. for(int i = 0; i < list.size(); i++)  
    2. for(int i = 0, size = list.size(); i < size; i++)  

    一般人都会认为第二种写法效率高。

    2.foreach:

    1. for(Object obj : list)  


    这是一种简洁的写法,只能对列表进行读取,无法修改。

    3.while:

    1. int size = list.size();  
    2. while(size-- > 0)  


    4.迭代:

    1. Object iter = list.iterator();  
    2. while(iter.hasNext()) {  
    3.   iter.next();  
    4. }  

    测试代码:

     针对以上几种方法编写的测试代码。

    1. public static void main(String[] args) {  
    2.       List<Integer> list = new ArrayList<Integer>();  
    3.   
    4.       int runTime = 1000;//执行次数  
    5.       for (int i = 0; i < 1000 * 1000; i++) {  
    6.           list.add(i);  
    7.       }  
    8.       int size = list.size();  
    9.       long currTime = System.currentTimeMillis();//开始分析前的系统时间  
    10.       //基本的for              
    11.       for(int j = 0; j < runTime; j++) {  
    12.           for (int i = 0; i < size; i++) {  
    13.               list.get(i);  
    14.           }  
    15.       }  
    16.       long time1 = System.currentTimeMillis();  
    17.   
    18.       //foreach  
    19.       for(int j = 0; j < runTime; j++) {  
    20.           for (Integer integer : list) {  
    21.           }  
    22.       }  
    23.       long time2 = System.currentTimeMillis();  
    24.   
    25.       for(int j = 0; j < runTime; j++) {  
    26.           //while  
    27.           int i = 0 ;  
    28.           while(i < size){  
    29.               list.get(i++);  
    30.           }  
    31.       }  
    32.       long time3 = System.currentTimeMillis();  
    33.   
    34.       for(int j = 0; j < runTime; j++) {//普通for循环  
    35.           for (int i = 0; i < list.size(); i++) {  
    36.               list.get(i);  
    37.           }  
    38.       }  
    39.       long time4 = System.currentTimeMillis();  
    40.   
    41.       for(int j = 0; j < runTime; j++) {//迭代  
    42.           Iterator<Integer> iter = list.iterator();  
    43.           while(iter.hasNext()) {  
    44.               iter.next();  
    45.           }  
    46.       }  
    47.       long time5 = System.currentTimeMillis();  
    48.   
    49.       long time = time1 - currTime ;  
    50.       System.out.print("use for:" + time);  
    51.       time = time2 - time1;  
    52.       System.out.print(" use foreach:" + time);  
    53.       time = time3 - time2;  
    54.       System.out.print(" use while:" + time);  
    55.       time = time4 - time3;  
    56.       System.out.print(" use for2:" + time);  
    57.       time = time5 - time4;  
    58.       System.out.print(" use iterator:" + time);  
    59.       System.out.println();  
    60.   }  

    输出结果(JDK1.6):

    1.

    use for:8695        use foreach:17091        use while:6867        use for2:7741        use iterator:14144

    2.

    use for:8432        use foreach:18126        use while:6905        use for2:7893        use iterator:13976

    3.

    use for:8584        use foreach:17177        use while:6875        use for2:7707        use iterator:14345

    结论:

    1.针对列表的 foreach的效率是最低:

    耗时是普通for循环的2倍以上。个人理解它的实现应该和iterator相似。

    2. list.size()的开销很小:

    list.size()次数多少对效率基本没有影响。查看ArrayList的实现就会发现,size()方法的只是返回了对象内的长度属性,并没有其它计算,所以只存在函数调用的开销。

    对数组的测试:

    将代码中的列表list换做数组再进行测试(iterator不适用),发现耗时基本为0。说明:
     
    3. 列表的get()方法开销不少

    应该主要是检测数据合法性时产生的。

    将执行次数增加100万倍,这时可以看出结果基本相等,并没有明显的差异。说明:

    4. 数组length也没有开销

    可见数组长度并不是每次执行的时候都要计算的。联想一下Java创建数组的时候要求必须指定数组的长度,编译处理的时候显然没有把这个值抛弃掉。

    网上有一篇类似的文章,它居然得出了一个foreach执行效率最高的结论。看一下它的测试代码就会发现一个要命的问题,它居然在执行每次循环的时候调用了System.out.print()方法将数组内容输出,难道他不知道这个操作耗时非常大吗,这样计算出的结果有什么用处呢。

  • 相关阅读:
    如何有效的写算法题的几个小tips
    题目
    记录加入博客园,申请开通cnblog
    关于套接字socket程序参数设置
    int main (int argc, const char * argv[0])及指针数组与数组指针
    sleep函数
    signal函数
    C htonl()函数
    位域unsigned char a:4
    关于TCP和UDP的一个理解
  • 原文地址:https://www.cnblogs.com/exmyth/p/4743366.html
Copyright © 2011-2022 走看看