Java 8 初探 - Parallel Array Sort

閱讀時間約 5 分鐘
此為過去的舊文,2014 年 5 月 18 日初次發表於 logdown。

最近比較懶一點,所以今天還是只看一個小東西。比較 Arrays 這個工具類別在 J2SE 7J2SE 8 的API文件,會發現 Arrays 多了幾組靜態函式:

  • stream(T[])
  • setAll(T[], IntFunction<T>)
  • parallelSetAll(T[], IntFunction<T>)
  • parallelPrefix(T[], BinaryOperator<T>)
  • spliterator(T[] array)
  • parallelSort(T[], Comparator<T>)

stream(T[])Java 8 初探 - Stream已經介紹過了,這裡只是把一個陣列包裝成 stream 來使用。

setAll(T[], IntFunction<T>)parallelSetAll(T[], IntFunction<T>)的功能是一樣的:用 IntFunction 的回傳值填滿整個 array,IntFunction 接受一個整數作為參數 (即 array 的索引值)。這類函式在產生特定數列時挺好用的,例如用來產生等差數列或等比數列。兩個函式只差在後者是以平行處理的方式填滿 array,速度較快 (也較耗資源)。


parallelPrefix(T[], BinaryOperator<T>) 可用目前索引的前一個數值 (binary operator 的 left 值) 和目前索引所指的值 (binary operator 的 right 值) 計算出新的數值 (有趣的是,Arrays 沒提供非 parallel 的版本),回傳值會填入原陣列中,所以binary operator 的 left 值都會是變更後的值。官方的例子假設元數列式 [2, 1, 0, 3],然後 BinaryOperator<T> 做加法運算,則運算後的數列是 [2, 3, 3, 6]6是根據陣列的第三個數 (left值) 加上第四個數 (right值) 取代原有的第四個數。

spliterator(T[] array) 是用來切割陣列,我猜當呼叫 parallelSort(T[], Comparator<T>) 或是用 stream(T[] array) 取得stream物件後,再次呼叫 parallel() 時,內部會用 spliterator(T[]) 取得 Spliterator 物件管理陣列的切割,用來做平行處理。

Arrays 的其他函式都介紹完了,該看今天的重點:parallelSort(T[], Comparator<T>)。在很早之前 Arrays 就有提供排序的函式,內部用的是 merge sort 演算法,使用時只需要提供比較任意兩物件順序的 Comparator 即可,這次新增的 parallelSort(T[], Comparator<T>) 就是平行處理的版本,所以我比較想知道平行處理版本所帶來的效能增益有多少?

這裡先宣告一個 SortStrategy<T> 的介面,然後分別提供使用非平行處理的SimpleSortStrategy 實作和使用平行處理的 ParallelSortStrategy 實作。接著提供一個函式 generateRandomValues(int) 產生指定數量的亂數數列。


事前準備完後就可以測試有沒有平行處理的差異了,下面的程式可以透過參數決定陣列的最小數量,以及測試要跑幾次,每次都會將陣列的數量加倍,藉此觀察加速是否和數量有關,例如數量越多加速越多?由於比較的次數和交換的次數都會影響到時間,所以先用 generateRandomValues(int) 產生一個亂數list,每種 strategy 執行前才轉為陣列 (轉換不列入時間計算),確保每個 strategy 都是用到相同亂數順序的陣列。測試的環境和先前測試 Java 8 初探 - Lazy Evaluation & Parallel Stream 相似,唯一的不同點是 JVM 從 1.8.0-b132 升級到 1.8.0_05-b13。


結果列於 Table 1,測試的陣列大小從一百萬個整數起跳,跑了 7 個測試到 64 百萬個數字,但跑第七個測試 (64 百萬個數字) 時會拋出 OutOfMemoryError 而失敗,因此只列到排序 32 百萬個數字的六筆比較數據。


Table 1 - The experiment result

Table 1 - The experiment result


從 Table 1 很明顯可以看到 parallelSort(T[], Comparator<T> 大概可以帶來 2.5 倍到接近 3 倍的效能增益 (和數量無關)。所以,結論是當需要處理大量資料的排序時,真的可以考慮使用 parallelSort(T[], Comparator<T>

52會員
102內容數
這是從 Medium 開始的一個專題,主要是想用輕鬆閒談的方式,分享這幾年軟體開發的心得,原本比較侷限於軟體架構,但這幾年的文章不僅限於架構,也聊不少流程相關的心得,所以趁換平台,順勢換成閒談軟體設計。
留言0
查看全部
發表第一個留言支持創作者!
Spirit的沙龍 的其他內容
Java 8 初探 - Lambda
閱讀時間約 6 分鐘
Java 8 初探 - Closure
閱讀時間約 5 分鐘
Java 8 初探 - Stream
閱讀時間約 7 分鐘
Java 8 初探 - Default Methods
閱讀時間約 5 分鐘
Java 8 初探 - Base64
閱讀時間約 5 分鐘
你可能也想看
【Java】SpringBoot 專案初始建置學習Spring Boot是Java工程師必備技能,文章分享瞭如何自學並快速上手Spring Boot開發,包括架構、開發工具、專案建立以及實作過程。
Thumbnail
avatar
2024-03-24
JAVA 呼叫 LINE NOTIFY 發訊息給群組本文章將介紹如何在LINE Notify上設定及使用權杖(access token)來進行通知功能。透過此API,可以使用curl或JAVA CODE來讓結果顯示在Line上面,達到及時的通知效果。
Thumbnail
avatar
艾倫の旅遊日誌 | 趴趴走找美食 | 心情寫照
2024-03-01
Java 不支持multi-inheritanceJava不能同時多重繼承 但是可以多層繼承
avatar
Genos's Coding Diary
2023-09-20
Java寫一次,到處執行WORA, Write Once Run Anywhere Java 不依賴於任何平台,Java可以在任何平台上執行,前提是那平台上要有安裝JVM Java的執行流程
Thumbnail
avatar
Genos's Coding Diary
2023-09-17
Java Development Kit (JDK)下載完JDK之後,在本機的環境變數中加入此JDK的bin路徑以便系統能識別使用 javac 是java compiler
Thumbnail
avatar
Genos's Coding Diary
2023-09-17
【Java】建立Maven專案使用第三方套件 相信很多初學者學python的原因,不外乎語法簡單、好上手、重點是有很多現成的套件可以玩。那麼,Java呢?有!當然有!而且還多到你不知道該選哪個好! 今天的文章主要示範如何在vscode新建立Java 的maven專案,並且透過maven安裝這些額外的套件(依賴)
Thumbnail
avatar
2023-09-02
【Java】安裝開始、開發環境建立 最近配合公司政策換了新電腦,重新回想起從頭建環境的惡夢。本篇文就來記錄一下如何開始踏入Java的第一步,方便起見也使用相對Eclipse、IntelliJ來說輕量不少的VScode作為編輯器。
Thumbnail
avatar
2023-07-05
Java Script自學經驗回顧來到學期2-3的階段,第一個作業就是打造餐廳清單。原本認為經過電影清單的學習經歷之後,對於打造餐廳清單應該也不會太過困難;沒想到我花了2個月的時間才把作業完整交出去。 在寫餐廳清單的初期,第一個碰到的問題就是首頁無法秀出餐廳評分這個選項。我試著參考其他同學的作品也改了版面的設計,卻始終無法出現餐廳評
avatar
奧莉薇
2023-02-28
Java Bird Coffee|通化街六張犁商圈,小巧而溫馨禾雀咖啡工作室位在通化街尾端,靠近六張犁的禾雀咖啡工作室,質樸的感覺是一家適合假日早晨來待上好一會兒的好去處。 主打自家烘培手沖及義式咖啡,最大特色還有自家製的麵包、甜點輕食,最喜歡吃的莫過於他們的鮮奶吐司。曾經住在這裡好長一段時間,週末去搶個一包可以在家裡烤來吃,是相當幸福的感覺。 冰羅馬咖啡則是我喝過最喜歡的
Thumbnail
avatar
Celine 寫在這裡
2023-02-06
Java abstract class 與 interface 的差別abstract class = 抽象類別 interface = 介面 抽象類別與介面都無法建立物件。 1. 使用abstract關鍵字來建立抽象類別,interface關鍵字建立介面。 interface只能繼承interface,且可以繼承多個:
Thumbnail
avatar
Vic Lin
2022-07-04