2015-11-23 53 views
3

StreamEx是一個強大的庫,但在某些時候,我不再需要它的超級大國了。如何解開StreamEx到「普通舊Java流」?

我該如何擺脫StreamEx內部開銷?這可能會造成問題嗎?

Ex。

public void process(Path path){ 
    StreamEx.of(Files.lines(path)) 
     .groupRuns(...) 
     //See below 
     .unwrap() 
     // 
     .map(...) 
     .forEach(...) 
} 
+7

我看到它的方式,StreamEx是一個Stream,標準操作被委託給一個Stream,所以實際上沒有開銷(除了創建一個對象之外)。我會讓它的作者給出正確的答案:)。 – Tunaki

回答

12

沒有公開的API方法來「解開」StreamEx流。這是有目的地完成的。一般而言,StreamEx類與原始的Stream API兼容,所以如果您需要將StreamEx傳遞給接受簡單Stream的某些代碼,則可以毫無顧忌地做到這一點。

使用StreamEx的開銷通常非常低:每個流程步驟中只有一個或多個額外的調用(其中一些可以通過JIT編譯器消除)。這個開銷(如果JIT沒有消除)只在流創建期間出現,而不是在評估期間出現,因此它不依賴於流中元素的數量。當終端操作發生時,處理被移交給原始流,因此在mapforEach評估期間的示例中,沒有StreamEx庫代碼正在運行。

如果你創建了很多簡單的短流,那麼StreamEx的開銷可能會有點顯着。例如,如果您在flatMap內創建了StreamEx實例。所以在這種情況下,如果性能很重要,並且您不需要嵌套Stream的特定StreamEx操作,那麼在flatMap內部避免StreamEx可能是個好主意。雖然根據我的測試,只有在非常人爲的情況下,差異才會顯着(比如說超過5%)。

請注意,與Stream API等效項相比,某些StreamEx操作進行了優化。例如,StreamEx.toList()通常比Stream.collect(Collectors.toList())更快。像StreamEx.of(persons).map(Person::getName).toList()這樣簡單的創建地圖收集操作可以比persons.stream().map(Person::getName).collect(Collectors.toList())工作快幾倍。