簡體   English   中英

使用謂詞通過parallelStream篩選並發映射或列表是否更快?

[英]Is it faster to use Predicates to filter a Concurrent Map or a List, using parallelStream?

我在List<FileMap>存儲了多個FileMap對象,目前大約有500,000個對象。

我正在使用謂詞使用parallelStream過濾列表。 我現在正在閱讀文檔,看到有一個名為Collectors.toConcurrentMap()的函數。 我對ConcurrentHashMap很熟悉,並且知道它更快,因為有多個線程可以划分地圖。

將簡單的ArrayList更改為toConcurrentMap ,然后將謂詞與parallelStream一起使用會更快嗎? 當前,如果我在該List上使用parallelStream並使用serialStream,則它的運行速度相同。

Map是key-value對的集合,其中鍵是唯一的。 您擁有的數據不是地圖,而是列表。 有很多問題:

  1. 嘗試將列表轉換為映射將需要提供鍵和值映射功能。
  2. 您最終將獲得比原始結構更大的結構。
  3. 您將必須確保鍵映射函數返回唯一值,從而使並行化成為不可能(可以使用同步,但這會大大降低性能)。
  4. 映射的結構比列表(實際上是數組)要復雜得多,並且構造它要花費更多的時間。
  5. ConcurrentMap具有額外的復雜性以確保線程安全-盡管它以比僅使所有方法都同步的更智能的方式完成,但它仍然會影響性能。
  6. 在地圖上進行迭代與數據的存儲方式沒有多大關系-無論如何,您都需要獲取一個設置值。

過濾列表中的元素可以進行大量(且很容易)並行化。 具有n核,其中n是列表的長度,您可以實現與log(n)一樣好的性能-這當然是使用專用的並行算法並使用圖形卡而不是CPU,因為它們雖然功能不那么強大,但具有數千個核心。

我對一個具有1億個整數的列表進行了一些測試,並使用並行流(大約350ms(我猜Java僅使用2個線程))依次處理了約700ms(嘗試將列表轉換為ConcurrentMap已耗盡內存)幾分鍾后出現錯誤。

您已經提到使用stream()parallelStream()不會改變性能。 我建議調查一下Java如何選擇在並行流中使用多少個線程(以及如何更改)。 這也受到資源的影響-運行CPU消耗的線程多於CPU內核數會由於上下文切換而降低性能。 我建議只使用與您擁有的內核數量一樣多的線程,或者減少一個線程-以便一個內核可以用於所有其他OS工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM