」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 對於簡單的操作,流總是比傳統集合慢嗎?

對於簡單的操作,流總是比傳統集合慢嗎?

發佈於2024-11-08
瀏覽:126

Are Streams Always Slower Than Traditional Collections for Simple Operations?

Java 8 流性能對比傳統集合

您最近涉足Java 8 並進行了非正式基準測試,以將其Stream API 與經典集合的表現進行比較。您的測試涉及過濾整數列表、提取偶數的平方根並將結果儲存在 Double 列表中。然而,您質疑測試的有效性,並渴望澄清真正的效能影響。

評估基準測試

您的初步結果,表明流比收集慢,引發了擔憂。為了確保更可靠的評估,必須解決潛在的錯誤並進行公平的測試。以下是一些注意事項:

  • 使用 LinkedList:LinkedList 不是結果清單的最佳選擇,因為它缺乏有效的隨機存取。考慮使用 ArrayList 代替。
  • 基準測試方法:手動基準測試可能容易出現不準確的情況。利用像 JMH (Java Microbenchmarking Harness) 這樣的基準測試框架來提供更精確和可靠的測量。

正確的基準測試結果

根據這些建議,讓我們重新回顧一下使用JMH 和改進的基準測試策略進行效能評估:

@OutputTimeUnit(TimeUnit.NANOSECONDS)
@BenchmarkMode(Mode.AverageTime)
@OperationsPerInvocation(StreamVsVanilla.N)
public class StreamVsVanilla {
    public static final int N = 10000;

    static List sourceList = new ArrayList();
    static {
        for (int i = 0; i  vanilla() {
        List result = new ArrayList(sourceList.size() / 2   1);
        for (Integer i : sourceList) {
            if (i % 2 == 0){
                result.add(Math.sqrt(i));
            }
        }
        return result;
    }

    @Benchmark
    public List stream() {
        return sourceList.stream()
                .filter(i -> i % 2 == 0)
                .map(Math::sqrt)
                .collect(Collectors.toCollection(
                    () -> new ArrayList(sourceList.size() / 2   1)));
    }
}

結果:

Benchmark                   Mode   Samples         Mean   Mean error    Units
StreamVsVanilla.stream      avgt        10       17.588        0.230    ns/op
StreamVsVanilla.vanilla     avgt        10       10.796        0.063    ns/op

調查結果

與初始結果相反,JMH基準測試清楚地表明傳統收集方法明顯快於

結論

基於這些改進的基準測試結果,我們可以得出結論:

  • Streams 本質上不是比集合慢。然而,在某些用例中,它們的開銷可能超過了好處,例如簡單的過濾和映射操作。
  • 流在程式碼簡單性和可維護性方面提供了顯著的優勢。它們簡化了資料處理管道並減少了樣板程式碼。
  • 對於效能關鍵的程式碼路徑,始終建議進行徹底的基準測試並考慮應用程式的具體要求。
最新教學 更多>

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3