Why list.sort() Beats stream().sorted() in Java: Benchmarks and Insights

This article investigates whether Java's list.sort() truly outperforms stream().sorted() by presenting simple demos, explaining the pitfalls of naive timing, and using JMH benchmarks to reveal that list.sort consistently runs faster due to lower overhead, while the performance gap remains small for typical data sizes.

Java Backend Technology
Java Backend Technology
Java Backend Technology
Why list.sort() Beats stream().sorted() in Java: Benchmarks and Insights

Is list.sort() Really Faster?

We start by asking the question and providing a simple demo that shows list.sort() taking 7 ms versus stream().sorted() taking 62 ms on a list of 10,000 random integers.

List<Integer> userList = new ArrayList<>();
Random rand = new Random();
for (int i = 0; i < 10000; i++) {
    userList.add(rand.nextInt(1000));
}
List<Integer> userList2 = new ArrayList<>();
userList2.addAll(userList);
Long startTime1 = System.currentTimeMillis();
userList2.stream().sorted(Comparator.comparing(Integer::intValue)).collect(Collectors.toList());
System.out.println("stream.sort耗时:" + (System.currentTimeMillis() - startTime1) + "ms");
Long startTime = System.currentTimeMillis();
userList.sort(Comparator.comparing(Integer::intValue));
System.out.println("List.sort()耗时:" + (System.currentTimeMillis() - startTime) + "ms");

The output shows List.sort() is faster, but swapping the order of the two measurements reverses the result, proving that such ad‑hoc timing is unreliable.

Why Simple Timing Is Unreliable

JVM JIT compilation and inlining can dramatically affect execution time, so a proper benchmark must warm up the code and measure many iterations.

Benchmarking is a scientific method that designs tests, tools, and systems to quantitatively compare performance metrics of a target.

JMH Benchmark

We use JMH to compare the two sorting methods across list sizes of 100, 10,000, and 100,000 elements.

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.results.format.ResultFormatType;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations = 2, time = 1)
@Measurement(iterations = 5, time = 5)
@Fork(1)
@State(Scope.Thread)
public class SortBenchmark {
    @Param({"100", "10000", "100000"})
    private int operationSize;
    private static List<Integer> arrayList;

    @Setup
    public void init() {
        arrayList = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < operationSize; i++) {
            arrayList.add(random.nextInt(10000));
        }
    }

    @Benchmark
    public void sort(Blackhole blackhole) {
        arrayList.sort(Comparator.comparing(e -> e));
        blackhole.consume(arrayList);
    }

    @Benchmark
    public void streamSorted(Blackhole blackhole) {
        arrayList = arrayList.stream().sorted(Comparator.comparing(e -> e)).collect(Collectors.toList());
        blackhole.consume(arrayList);
    }
}

The benchmark results (shown in the image below) confirm that list.sort() consistently outperforms stream().sorted() for all tested sizes.

Benchmark result
Benchmark result

Why List.sort Is Faster

The stream version incurs extra overhead: converting the list to a stream, processing the pipeline, and collecting the result back into a list. This overhead is small compared to the total sorting time but still makes the stream version slower.

In most real‑world scenarios with hundreds or thousands of elements, the difference is negligible, and developers may prefer the more expressive stream API.

Conclusion

For pure list sorting, list.sort() is more efficient than stream().sorted() because it avoids the additional stream conversion and collection steps. However, the performance gap is modest, and the choice should consider code readability and specific use cases.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaperformanceBenchmarkJMHlist.sortstream.sorted
Java Backend Technology
Written by

Java Backend Technology

Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.