1. 程式人生 > >for i和for each和Java8的forEach效能測試,到底誰快的測試

for i和for each和Java8的forEach效能測試,到底誰快的測試

有說這個快,有說那個快,但是,靠嘴不頂用啊。還是測試一下就知道啦。

(Lists.newArrayList(); 這個是guava裡面的一個集合初始化的工具)

如下 :

先是main方法吧

    /**
     * 測試不同for的效率問題
     */
    private static void testForEfficiency() {
        List<String> arrayList = CollectionUtil.getArrayList();
        List<String> linkedList = CollectionUtil.getLinkedList();
        testForI(arrayList, linkedList);
        testForEach(arrayList, linkedList);
        testForLambda(arrayList, linkedList);
    }

然後是獲取2個集合的方法。
package com.lxk.util;

import com.google.common.collect.Lists;

import java.util.List;

/**
 * 自定義集合告警類
 *
 * @author lxk on 2017/11/13
 */
public class CollectionUtil {
    private static final int SIZE = 1000000;

    /**
     * 獲得底層是陣列的list集合
     */
    public static List<String> getArrayList() {
        List<String> list = Lists.newArrayListWithExpectedSize(SIZE);
        for (Integer i = 0; i < SIZE; i++) {
            list.add(i.toString());
        }
        return list;
    }

    /**
     * 獲得底層是連結串列的list集合
     */
    public static List<String> getLinkedList() {
        List<String> list = Lists.newArrayListWithExpectedSize(SIZE);
        for (Integer i = 0; i < SIZE; i++) {
            list.add(i.toString());
        }
        return list;
    }
}

然後就是三個效能方法
    /**
     * for i
     *
     * @param arrayList  arrayList
     * @param linkedList linkedList
     */
    private static void testForI(List<String> arrayList, List<String> linkedList) {
        int size = arrayList.size();
        StringBuilder sb = new StringBuilder();
        long a = System.currentTimeMillis();
        for (int i = 0; i < size; i++) {
            sb.append(arrayList.get(i));
        }
        PrintUtil.printRunTime(a, "for i for arrayList");

        size = linkedList.size();
        sb = new StringBuilder();
        a = System.currentTimeMillis();
        for (int i = 0; i < size; i++) {
            sb.append(linkedList.get(i));
        }
        PrintUtil.printRunTime(a, "for i for linkedList");
    }

    /**
     * for each
     *
     * @param arrayList  arrayList
     * @param linkedList linkedList
     */
    private static void testForEach(List<String> arrayList, List<String> linkedList) {
        StringBuilder sb = new StringBuilder();
        long a = System.currentTimeMillis();
        for (String s : arrayList) {
            sb.append(s);
        }
        PrintUtil.printRunTime(a, "for each for arrayList");

        sb = new StringBuilder();
        a = System.currentTimeMillis();
        for (String s : linkedList) {
            sb.append(s);
        }
        PrintUtil.printRunTime(a, "for each for linkedList");
    }

    /**
     * Java 8 的for迴圈
     *
     * @param arrayList  arrayList
     * @param linkedList linkedList
     */
    private static void testForLambda(List<String> arrayList, List<String> linkedList) {
        StringBuilder sb = new StringBuilder();
        long a = System.currentTimeMillis();
        arrayList.forEach(sb::append);
        PrintUtil.printRunTime(a, "Lambda for arrayList");

        sb = new StringBuilder();
        a = System.currentTimeMillis();
        linkedList.forEach(sb::append);
        PrintUtil.printRunTime(a, "Lambda for linkedList");
    }

還有個列印時間的方法
package com.lxk.util;

/**
 * @author lxk on 2017/9/27
 */
public class PrintUtil {
    public static void divideLine() {
        System.out.println("--------------分界符--------------");
    }

    /**
     * @param a        long a=System.currentTimeMillis();
     * @param describe 執行時間的描述
     */
    public static void printRunTime(long a, String describe) {
        System.out.println(describe + " 執行耗時 : " + (System.currentTimeMillis() - a) + " 毫秒 ");
    }
}

最後就是這些個程式碼實際執行的結果
for i for arrayList 執行耗時 : 105 毫秒 
for i for linkedList 執行耗時 : 22 毫秒 
for each for arrayList 執行耗時 : 44 毫秒 
for each for linkedList 執行耗時 : 25 毫秒 
Lambda for arrayList 執行耗時 : 74 毫秒 
Lambda for linkedList 執行耗時 : 44 毫秒 

for i for arrayList 執行耗時 : 164 毫秒 
for i for linkedList 執行耗時 : 29 毫秒 
for each for arrayList 執行耗時 : 91 毫秒 
for each for linkedList 執行耗時 : 27 毫秒 
Lambda for arrayList 執行耗時 : 94 毫秒 
Lambda for linkedList 執行耗時 : 43 毫秒 

for i for arrayList 執行耗時 : 114 毫秒 
for i for linkedList 執行耗時 : 26 毫秒 
for each for arrayList 執行耗時 : 52 毫秒 
for each for linkedList 執行耗時 : 28 毫秒 
Lambda for arrayList 執行耗時 : 92 毫秒 
Lambda for linkedList 執行耗時 : 54 毫秒 

for i for arrayList 執行耗時 : 130 毫秒 
for i for linkedList 執行耗時 : 45 毫秒 
for each for arrayList 執行耗時 : 72 毫秒 
for each for linkedList 執行耗時 : 30 毫秒 
Lambda for arrayList 執行耗時 : 96 毫秒 
Lambda for linkedList 執行耗時 : 45 毫秒

for i for arrayList 執行耗時 : 127 毫秒 
for i for linkedList 執行耗時 : 26 毫秒 
for each for arrayList 執行耗時 : 103 毫秒 
for each for linkedList 執行耗時 : 36 毫秒 
Lambda for arrayList 執行耗時 : 123 毫秒 
Lambda for linkedList 執行耗時 : 58 毫秒 

也就放這麼幾次的執行結果吧,有興趣的可以自己跑一下。

為什麼:

    for each是jdk5.0新增加的一個迴圈結構,可以用來處理集合中的每個元素而不用考慮集合定下標。
    格式就不說了

迴圈的集合:collection必須是一個數組或者是一個實現了lterable介面的類物件。
(Iterator<E> iterator(); List 集合實現了這個介面,它的子類當然也實現了,好吧collection也是實現的,所以這裡可以看到的集合都可以用for each)
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set

使用for each迴圈語句的優勢在於更加簡潔,更不容易出錯,不必關心下標的起始值和終止值。
forEach不是關鍵字,關鍵字還是for,語句是由iterator實現的,他們最大的不同之處就在於remove()方法上。
 
 一般呼叫刪除和新增方法都是具體集合的方法,例如:
List list = new ArrayList(); list.add(...); list.remove(...);
但是,如果在for each迴圈的過程中呼叫集合的remove()方法,就會導致迴圈出錯,
因為迴圈過程中list.size()的大小變化了,就導致了錯誤。 所以,如果想在迴圈語句中刪除集合中的某個元素,
就要用迭代器iterator的remove()方法,因為它的remove()方法不僅會刪除元素,還會維護一個標誌,
用來記錄目前是不是可刪除狀態,這就涉及到原始碼了,想考慮了可以看下這個異常報錯,連結如下:
( -->點選這個     http://blog.csdn.net/qq_27093465/article/details/52033629)
例如,你不能連續兩次呼叫它的remove()方法,呼叫之前至少有一次next()方法的呼叫。  
forEach就是為了讓用iterator迴圈訪問的形式簡單,寫起來更方便。當然功能不太全,所以但如有刪除操作,還是要用它原來的形式。

使用for迴圈與使用迭代器iterator的對比
 
效率上的各有優勢
採用ArrayList對隨機訪問比較快,而for迴圈中的get()方法,採用的即是隨機訪問的方法,因此在ArrayList裡,for迴圈較快
採用LinkedList則是順序訪問比較快,iterator中的next()方法,採用的即是順序訪問的方法,因此在LinkedList裡,使用iterator較快
從資料結構角度分析,for迴圈適合訪問順序結構,可以根據下標快速獲取指定元素.而Iterator 
適合訪問鏈式結構,因為迭代器是通過next()和Pre()來定位的.可以訪問沒有順序的集合. 
而使用 Iterator 的好處在於可以使用相同方式去遍歷集合中元素,而不用考慮集合類的內部實現(只要它實現了 java.lang.Iterable 介面),
如果使用 Iterator 來遍歷集合中元素,一旦不再使用 List 轉而使用 Set 來組織資料,
那遍歷元素的程式碼不用做任何修改,如果使用 for 來遍歷,
那所有遍歷此集合的演算法都得做相應調整,
因為List有序,Set無序,結構不同,
他們的訪問演算法也不一樣.

相關推薦

for ifor eachJava8的forEach效能測試到底測試

有說這個快,有說那個快,但是,靠嘴不頂用啊。還是測試一下就知道啦。 (Lists.newArrayList(); 這個是guava裡面的一個集合初始化的工具) 如下 : 先是main方法吧

Fio安裝、測試Gfio圖形化測試I/O讀寫效能

Fio安裝 1、下載安裝gtk庫:sudo yum install gtk2-devel glib2-devel 3、解壓fio包:tar -zxvf fio-2.1.7.tar.gz 4、cd fio-2.1.7 5、./configure --enable-gfio

電腦效能一目瞭然教你用測試軟體測試整機效能

一臺膝上型電腦或者是一臺DIY臺式電腦,都是由處理器、顯示卡、硬碟等配件構成,而每個配件都有自己的效能,效能是高是低我們可以進行單項測試。對於整機效能我們也可以對其進行測試,來看看它的真實效能到底如何。     CPU中文名叫中央處理器,它是一臺電腦中最核心的部

jquery eachfor循環比較

ria 所有 gpo i++ pre func orm bre each 例: var arr = $(‘#templateForm‘).serializeArray(); $.each(arr,function(k,v){ if(!v.value){

for,forEach,for in ,for of,$.each$().each應用

In 我們 應用 你我 幫助 感覺 別人 收益 必須 今天嚴重的意識到,只看不總結,就如同走馬觀花,得到的也必是浮光掠影,看完以後感覺自己學富五車,才高八鬥,實則不辨菽麥,前輩們說的一點也不錯,寫博客這件事必須的堅持,因為誰也不想讓自己的博客變成自己都不願意進的垃圾站,所以

for each...infor...in

for...in 官方解釋:for...in語句以任意順序遍歷一個物件的可列舉屬性。對於每個不同的屬性,語句都會被執行。 語法:for (變數 in 物件) { 在此執行程式碼(每次迴圈一次,就會把這個物件的屬性賦值給這個變數,然後就可以來檢視有哪些屬性,或者更改屬性等) }1.迭代中增加屬性

Iterator原始碼解析及for-each迴圈

在使用foreach迴圈遍歷集合的過程中,如果集合被修改了,會丟擲ConcurrentModificationException異常。 以這段程式碼為例子: public class SynProblem { List<Widget> widgetList

JavaScript——forfor in 的效能比較與for迴圈的優化方案

在JavaScript中,我們遍歷陣列的時候經常需要用到for和for in。今天來比較一下這兩個遍歷方法的效能,並提供優化方案。 1.for 和for in的效能比較 我們都知道,for 和for in的時間複雜度一樣,但是其效能有些許差距。具體有多大差距呢,下面我們來

Java中System.arraycopy, Object.clone, Arrays.copyOffor 4種陣列複製方式的效能比較

用程式碼說話 package InterviewDirectory.binaryTree_example.System.arraycopy_Arrays; import java.util.Arrays; /** * Created by xxx on

numpy array list 的相互轉化 [np.where(x == i)[0] for i in range(10)] 的意思

1.list 轉 numpy array a = [0,2,3,2,1,2,4,5,6,7,8,6,5,4,3,2,7,8,9,6,5,7,8,9,6,9,1,2,2,5,6,8,8,9,7,0] x = np.array(a) print(x)  2. numpy arr

iteratorfor語句解析list的效能對比

偶然看到一些程式碼用Iterator來獲取list的引數, 如下 Iterator<String> it = list.iterator(); String staffCode; while(it.hasNext()){ staffCode = i

iterablefor-each迴圈集合的注意事項

Java中,for-each迴圈簡化了任何Collection或array的遍歷過程,但並不是每個Java程式設計師都瞭解本文將要描述的for-each 迴圈的一些細節。與 Java5 釋出的其他術語:釋放別名泛型,自動封裝和可變引數不同,Java開發者對for-each迴圈的使用比任何其他特性更加頻繁,但

js中 jquery中的each迴圈for迴圈的區別

each定義和用法each() 方法規定為每個匹配元素規定執行的函式。提示:返回 false 可用於及早停止迴圈。都知道在java中         continue,跳過本次迴圈   break   結束這個迴圈    return 結束方法那麼在js中,用jquery 

關於JavaScript閉包中for迴圈執行順序(thistrs[i]問題)

.over{ Background:red; } .out{ Background:white; } var trs=document.getElementsByTagName("tr"); for(var i=0;i<trs.length;i+

forEachmapfor方法的區別

turn 而不是 ber num 遍歷數組 風格 cnblogs ron () 那麽接下來,我繼續做分析,為什麽更推薦用.map(),而不是.forEach()? 首先,.map()要比.forEach()執行速度更快。雖然我也說過執行速度不是我們需要考慮的主要因素,但是他

轉 navicat for mysql 的 刪減表 清空表

epo popu rep jce 包含 mod pla aid 5% 刪除操作在執行的語句就是delete語句 也就是可以按照後邊的where條件進行刪除指定行,當然也可以不加where條件,把所有的數據刪除 清空所執行的語句是truncate,也就是把這個表裏所有

15.Iteratorfor...of循環

表示 四種 for nbsp 排列 概念 數據 命令 需要 1.Iterator(遍歷器)的概念 JavaScript原有的表示“集合”的數據結構,主要是數組(Array)和對象(Object),ES6又添加了Map和Set。這樣就有了

for循環for增強

步驟 條件 初始化 str 增強的for循環 類型 缺點 print 狀態 For循環: 在編程的過程中,會有很多需要重復做的事。在編程的過程中把一些重復執行 的代碼采用循環結構來描述,可以大大簡化編碼工作,for循環就是循環中的一種還有while和dowh

鎖定數據行 for updatefor update nowait

for update和for update nowait鎖定數據行select * from emp t where t.deptno=‘20‘ for update nowait;這樣就鎖定了emp表中deptno = 20的那行數據註意:通過for update鎖定後,這些行不能修改了,但是還可以查詢f

可枚舉屬性不可枚舉屬性(for...in循環Objec.keys()Object.getOwnPropertyNames())

bject 區別 names 所有 每一個 原型 () get for for...in循環是 遍歷對象的每一個可枚舉屬性,包括原型鏈上面的可枚舉屬性,而Object.keys()只是遍歷自身的可枚舉屬性,不可以遍歷原型鏈上的可枚舉屬性. 這是for...in和Objec