Why List.sort() Is Faster Than Stream.sorted() in Java: Benchmarks and Analysis
This article examines the performance difference between Java's List.sort() and Stream.sorted() by presenting simple demos, discussing JIT warm‑up effects, and using JMH benchmarks to show that native list sorting generally outperforms the stream‑based approach.
The article investigates why the native list.sort() method usually runs faster than sorting via list.stream().sorted() in Java.
A quick demo creates a list of random integers, sorts it once with list.sort() and once with the stream API, and prints the elapsed time.
List
userList = new ArrayList<>();
Random rand = new Random();
for (int i = 0; i < 10000; i++) {
userList.add(rand.nextInt(1000));
}
List
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 typically shows List.sort() taking around 7 ms while the stream version takes about 62 ms, suggesting the native sort is faster.
Reversing the order of the two measurements flips the results (e.g., 68 ms vs 13 ms), demonstrating that simple timing is affected by JIT compilation and warm‑up, so it cannot prove a definitive conclusion.
To obtain reliable data, the article introduces a proper JMH benchmark that measures both methods across different collection sizes (100, 10 000, 100 000) with warm‑up iterations and multiple measurement runs.
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
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 JMH results confirm that list.sort() consistently outperforms stream().sorted() for all tested sizes.
The performance gap stems from two main factors: (1) the stream API adds overhead by converting the list to a stream and then collecting the sorted elements back into a list, and (2) the actual sorting step in the stream pipeline still invokes the same native sort, so the extra stream processing adds extra time.
In most real‑world scenarios with modest data volumes, the difference is negligible, but when raw sorting speed matters, using list.sort() is the preferred choice.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
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.