1. 程式人生 > >lambda表示式foreach和普通for迴圈效能比較

lambda表示式foreach和普通for迴圈效能比較

java 8的新特性之一就是lambda表示式,其中lambda表示式的foreach迴圈最為引人注目,現比較下lambda表示式foreach和普通for迴圈的效能測試。程式碼如下:

  public static void main(String[] args){
       List<String> list = new ArrayList<>();
       for(int i =0;i<10000;i++){
           list.add(String.valueOf(i));
       }
        long begin = System.currentTimeMillis();
        for(Object s : list){
            s.toString();
        }
        long end = System.currentTimeMillis();
        System.out.println("普通for迴圈耗時"+(end-begin)+"ms");
        begin = System.currentTimeMillis();
        list.forEach(e->{
            e.toString();
        });
        end = System.currentTimeMillis();
        System.out.println("普通lambda表示式foreach耗時"+(end-begin)+"ms");
        begin = System.currentTimeMillis();
        list.stream().forEach(e->{
            e.toString();
        });
        end = System.currentTimeMillis();
        System.out.println("單管道stream耗時"+(end-begin)+"ms");
        begin = System.currentTimeMillis();
        list.parallelStream().forEach(e->{
            e.toString();
        });
        end = System.currentTimeMillis();
        System.out.println("多管道stream耗時"+(end-begin)+"ms");
    }

 測試結果:

普通for迴圈耗時1ms
普通lambda表示式foreach耗時40ms
單管道stream耗時51ms
多管道stream耗時38ms

為何lambda表示式的效能比普通的還差,我猜測是因為:list.parallelStream()是併發處理的,大量的執行緒上下文切換導致效能下降。如何證明?那就把for迴圈裡的處理時間設定長一點吧,設定成如下程式碼: 

 public static void main(String[] args){
       List<String> list = new ArrayList<>();
       for(int i =0;i<10000;i++){
           list.add(String.valueOf(i));
       }
        long begin = System.currentTimeMillis();
        for(Object s : list){
            try {
                Thread.sleep(1);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            s.toString();
        }
        long end = System.currentTimeMillis();
        System.out.println("普通for迴圈耗時"+(end-begin)+"ms");
        begin = System.currentTimeMillis();
        list.stream().forEach(e->{
            try {
                Thread.sleep(1);
            } catch (InterruptedException e1) {
                 e1.printStackTrace();
            }
            e.toString();
        });
        end = System.currentTimeMillis();
        System.out.println("單管道stream耗時"+(end-begin)+"ms");
        begin = System.currentTimeMillis();
        list.parallelStream().forEach(e->{
            try {
                Thread.sleep(1);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            e.toString();
        });
        end = System.currentTimeMillis();
        System.out.println("多管道stream耗時"+(end-begin)+"ms");
    }

測試結果:

普通for迴圈耗時10104ms
普通lambda表示式foreach耗時10144ms
單管道stream耗時10084ms
多管道stream耗時2512ms

由此可見,對於耗時的操作用lambda表示式的for迴圈,如資料庫的IO操作,多執行緒充分利用CPU資源,傳統方式跟單管道stream的處理效率相差無幾,多管道parallelStream的處理效率最高;對於不太耗時的操作使用普通for迴圈,比如純CPU計算型別的操作,單執行緒效能更高,減少上下文切換的開銷。