Java里多個Map的性能比較(TreeMap、HashMap、ConcurrentSkipListMap)


比較Java原生的 3種Map的效率。
1.  TreeMap
2.  HashMap
3.  ConcurrentSkipListMap

模擬150W以內海量數據的插入和查找,通過增加和查找兩方面的性能測試,結果如下:

Map類型

插入 查找(在100W數據量中)
  10W 50W 100W 150W 0-1W 0-25W 0-50W
Concurrent
SkipListMap
62 ms 227 ms 433 ms 689ms 7 ms 80 ms 119 ms
HashMap  18 ms 93 ms 217 ms 303ms 2 ms 13 ms 45 ms
TreeMap  33 ms 228 ms 429 ms 584 ms 4ms 34 ms 61 ms


圖1- 1常數和logn函數效率對比示例圖(橫軸-n數據量,縱軸-f(n)時間)


TreeMap基於紅黑樹(一種自平衡二叉查找樹)實現的,時間復雜度平均能達到O(log n)。
HashMap是基於散列表實現的,時間復雜度平均能達到O(1)。
ConcurrentSkipListMap是基於跳表實現的,時間復雜度平均能達到O(log n)。

(1) TreeMap與HashMap相比較

Ø  HashMap里面存入的鍵值對在取出的時候是隨機的,它根據鍵的HashCode值存儲數據,根據鍵可以直接獲取它的值,具有很快的訪問速度。在Map 中插入、刪除和定位元素,HashMap是最好的選擇。

Ø  TreeMap取出來的是排序后的鍵值對。插入、刪除需要維護平衡會犧牲一些效率。但如果要按自然順序或自定義順序遍歷鍵,那么TreeMap會更好。

 


(2) TreeMap與ConcurrentSkipListMap相比較

 

Ø  Skip list(跳表)是一種可以代替平衡樹的數據結構,默認是按照Key值升序的。Skip list讓已排序的數據分布在多層鏈表中,以0-1隨機數決定一個數據的向上攀升與否,通過“空間來換取時間”的一個算法,在每個節點中增加了向前的指 針,在插入、刪除、查找時可以忽略一些不可能涉及到的結點,從而提高了效率。
從概率上保持數據結構的平衡比顯示的保持數據結構平衡要簡單的多。對於大多數應用,用Skip list要比用樹算法相對簡單。由於Skip list比較簡單,實現起來會比較容易,雖然和平衡樹有着相同的時間復雜度(O(logn)),但是skip list的常數項會相對小很多。Skip list在空間上也比較節省。一個節點平均只需要1.333個指針(甚至更少)。
                
圖1-2 Skip list結構圖(以7,14,21,32,37,71,85序列為例)

(1) 由很多層結構組成,level是通過一定的概率隨機產生的。
(2) 每一層都是一個有序的鏈表,默認是升序,也可以根據創建映射時所提供的Comparator進行排序,具體取決於使用的構造方法。
(3) 最底層(Level 1)的鏈表包含所有元素。
(4) 如果一個元素出現在Level i 的鏈表中,則它在Level i 之下的鏈表也都會出現。
(5) 每個節點包含兩個指針,一個指向同一鏈表中的下一個元素,一個指向下面一層的元素。

Ø  ConcurrentSkipListMap具有Skip list的性質 ,並且適用於大規模數據的並發訪問。多個線程可以安全地並發執行插入、移除、更新和訪問操作。與其他有鎖機制的數據結構在巨大的壓力下相比有優勢。

本測試查找方法使用Map的get方法,循環、離散獲取。對於ConcurrentSkipListMap,獲得順序片段,可用subMap()方法,提取50w的子序列只需要1ms,具有巨大優勢。 SkipListMap的范圍查詢效率比HashMap和TreeMap效率都要高。hashMap線程不安全,也實現Map接口的hashTable安全


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM