Why List.sort() Is Faster Than Stream.sorted() in Java: Benchmarks and Analysis
This article investigates the performance difference between Java's List.sort() and Stream.sorted(), providing simple demos, JMH benchmark results, and analysis of underlying overheads to explain why the native list sorting is generally faster than sorting via streams.
The article revisits the claim that List.sort() outperforms Stream.sorted() by first presenting a simple demo that measures execution time for both methods 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 first run shows List.sort() taking about 7 ms versus 62 ms for the stream version, suggesting the native sort is faster, but a second ordering of the calls reverses the results, demonstrating that such naive timing is unreliable.
To obtain reliable measurements the article introduces JMH (Java Microbenchmark Harness) and provides a benchmark class that tests both sorting approaches for collection 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.ThreadLocalRandom;
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(value = {"100", "10000", "100000"})
private int operationSize;
private static List<Integer> arrayList;
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(SortBenchmark.class.getSimpleName())
.result("SortBenchmark.json")
.mode(Mode.All)
.resultFormat(ResultFormatType.JSON)
.build();
new Runner(opt).run();
}
@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 confirm that List.sort() consistently has lower average execution time than Stream.sorted() , although the difference shrinks for larger data sets.
The overhead stems from creating a stream, applying the sorting operation, and then collecting the elements back into a list; the native List.sort() directly sorts the underlying array without these extra steps. Additionally, JIT compilation and inlining affect timings, so proper warm‑up is essential.
In summary, while streams provide expressive and concise code, for pure list sorting the built‑in List.sort() is generally faster, and developers should use benchmarks like JMH rather than ad‑hoc timing when performance matters.
Note: the discussion concerns sequential streams; parallel streams have different characteristics.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.