map的遍歷性能測試

java中遍歷通過不同的元素遍歷map的方式有3種:1.通過keySet遍歷;2.通過entrySet遍歷;3.獲取values遍歷value。通過不同的方式遍歷又分爲foreach和iterator。因爲本文按照這幾個維度,以不同數據量來分別測試所需時間。


主要測試方法如下:

private static void valuesIterator(Map<String, String> map) {
    /** values   iterator遍歷 */
    long start = System.currentTimeMillis();
    Iterator it = map.values().iterator();
    while (it.hasNext()){
        String value = (String)it.next();
    }
    long end = System.currentTimeMillis();
    System.out.println("values   iterator遍歷耗時:" + (end - start) + "ms");
}

private static void valuesForeach(Map<String, String> map) {
    /** values foreach遍歷 */
    long start = System.currentTimeMillis();
    for (String value : map.values()){
    }
    long end = System.currentTimeMillis();
    System.out.println("values   foreach遍歷耗時:"+(end-start)+"ms");
}

private static void entryIterator(Map<String, String> map) {
    /** Map.Entry<K, V>   iterator遍歷 */
    long start = System.currentTimeMillis();
    Iterator it = map.entrySet().iterator();
    while (it.hasNext()){
        Map.Entry<String,String> entry = (Map.Entry<String,String>)it.next();
        String key = entry.getKey();
        String value = entry.getValue();
    }
    long end = System.currentTimeMillis();
    System.out.println("Map.Entry<K, V>   iterator遍歷耗時:"+(end-start)+"ms");
}

private static void entryForeach(Map<String, String> map) {
    /** Map.Entry<K, V>   foreach遍歷 */
    long start = System.currentTimeMillis();
    for (Map.Entry<String,String> entry : map.entrySet()){
        String key = entry.getKey();
        String value = entry.getValue();
    }
    long end = System.currentTimeMillis();
    System.out.println("Map.Entry<K, V>   foreach遍歷耗時:" + (end - start) + "ms");
}

private static void keySetIterator(Map<String, String> map) {
    /** keySet   iterator遍歷 */
    long start = System.currentTimeMillis();
    Iterator it = map.keySet().iterator();
    while (it.hasNext()){
        String key = (String)it.next();
        String value = map.get(key);
    }
    long end = System.currentTimeMillis();
    System.out.println("keySet   iterator遍歷耗時:"+(end-start)+"ms");
}

private static void keySetForeach(Map<String, String> map) {
    /** keyset foreach遍歷 */
    long start = System.currentTimeMillis();
    for (String key : map.keySet()){
        String value = map.get(key);
    }
    long end = System.currentTimeMillis();
    System.out.println("keyset   foreach遍歷耗時:"+(end-start)+"ms");
}
除此之外,還有一些類似的方法,這裏就不都展示出來了。

private static void test(int n) {
    System.out.println();
    System.out.println("-------------------------");
    System.out.println(n+"條數據量測試:");
    System.out.println();
    Map<String,String> map = new HashMap();
    for (int i = 0 ; i < n ; i++){
        map.put(i+"aa",i+"ss");
    }
    System.out.println("1.遍歷key - value");
    keySetForeach(map);
    keySetIterator(map);
    entryForeach(map);
    entryIterator(map);
    System.out.println();
    System.out.println("2.遍歷key");
    keySetKeyForeach(map);
    keySetKeyIterator(map);
    entryKeyForeach(map);
    entryKeyIterator(map);
    System.out.println();
    System.out.println("3.遍歷value");
    keySetValueForeach(map);
    keySetValueIterator(map);
    entryValueForeach(map);
    entryValueIterator(map);
    valuesForeach(map);
    valuesIterator(map);
}
public static void main(String[] args) {
    test(50000);
    test(100000);
    test(1000000);
}

這裏通過3個數量級測試:5萬條數據,10萬條數據,100萬條數據。


測試結果:


-------------------------
50000條數據量測試:


1.遍歷key - value
keyset   foreach遍歷耗時:16ms
keySet   iterator遍歷耗時:13ms
Map.Entry<K, V>   foreach遍歷耗時:10ms
Map.Entry<K, V>   iterator遍歷耗時:11ms


2.遍歷key
keyset   foreach遍歷耗時:8ms
keySet   iterator遍歷耗時:7ms
Map.Entry<K, V>   foreach遍歷耗時:9ms
Map.Entry<K, V>   iterator遍歷耗時:8ms


3.遍歷value
keyset   foreach遍歷耗時:11ms
keySet   iterator遍歷耗時:12ms
Map.Entry<K, V>   foreach遍歷耗時:8ms
Map.Entry<K, V>   iterator遍歷耗時:7ms
values   foreach遍歷耗時:8ms
values   iterator遍歷耗時:8ms


-------------------------
100000條數據量測試:


1.遍歷key - value
keyset   foreach遍歷耗時:13ms
keySet   iterator遍歷耗時:14ms
Map.Entry<K, V>   foreach遍歷耗時:10ms
Map.Entry<K, V>   iterator遍歷耗時:13ms


2.遍歷key
keyset   foreach遍歷耗時:8ms
keySet   iterator遍歷耗時:8ms
Map.Entry<K, V>   foreach遍歷耗時:9ms
Map.Entry<K, V>   iterator遍歷耗時:10ms


3.遍歷value
keyset   foreach遍歷耗時:13ms
keySet   iterator遍歷耗時:12ms
Map.Entry<K, V>   foreach遍歷耗時:9ms
Map.Entry<K, V>   iterator遍歷耗時:8ms
values   foreach遍歷耗時:8ms
values   iterator遍歷耗時:9ms


-------------------------
1000000條數據量測試:


1.遍歷key - value
keyset   foreach遍歷耗時:66ms
keySet   iterator遍歷耗時:65ms
Map.Entry<K, V>   foreach遍歷耗時:47ms
Map.Entry<K, V>   iterator遍歷耗時:47ms


2.遍歷key
keyset   foreach遍歷耗時:41ms
keySet   iterator遍歷耗時:41ms
Map.Entry<K, V>   foreach遍歷耗時:42ms
Map.Entry<K, V>   iterator遍歷耗時:42ms


3.遍歷value
keyset   foreach遍歷耗時:66ms
keySet   iterator遍歷耗時:64ms
Map.Entry<K, V>   foreach遍歷耗時:43ms
Map.Entry<K, V>   iterator遍歷耗時:43ms
values   foreach遍歷耗時:42ms
values   iterator遍歷耗時:44ms


結果分析:

這裏暫時不對key - value的複雜度、離散程度已經衝突進行測試,僅以簡單的數字字符爲主測試。

hashmap:

1.遍歷key - value的時候,通常情況下,使用entrySet遍歷比keySet更好,因爲keySet要先拿到key,後查出value。

2.遍歷key的時候,通常情況下,使用keySet遍歷比entrySet更好,畢竟entrySet除了包含key之外還有value,需要更多的資源。

3.遍歷value的時候,通常情況下,使用values最方便,其次entrySet。

4.遍歷的方式推薦使用foreach循環,理由有二:1.性能稍好一些;2.代碼簡潔。

5.數據量越大,這種性能差異越明顯。


treemap:

使用treemap測試,結論與hashmap一致,由於其查詢特性決定,上述結論更加明顯。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章