Last active
June 15, 2025 19:36
-
-
Save SaiManojCheruvu/20e9ee94b160db82426ffa9e32cbcb3a to your computer and use it in GitHub Desktop.
toList() vs fixed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.stream.optimizer; | |
import java.util.*; | |
import java.util.stream.*; | |
public class Benchmark { | |
private static class User { | |
private final int id; | |
private final String name; | |
private final String email; | |
public User(int id) { | |
this.id = id; | |
this.name = "User-" + id; | |
this.email = "user" + id + "@example.com"; | |
} | |
public String getName() { | |
return name; | |
} | |
} | |
private static List<User> generateUsers(int size) { | |
return IntStream.range(0, size) | |
.mapToObj(User::new) | |
.collect(Collectors.toList()); | |
} | |
private static <T> Collector<T, ?, List<T>> toExactList(int size) { | |
return Collector.of( | |
() -> new ArrayList<>(size), // Supplier: pre-sized ArrayList | |
List::add, // Accumulator: add elements | |
(list1, list2) -> { // Combiner: used only in parallel | |
list1.addAll(list2); // Merges partial results (not used in sequential) | |
return list1; | |
}, | |
Collector.Characteristics.IDENTITY_FINISH | |
); | |
} | |
private static void runBenchmark(int dataSize, int warmupRuns, int measurementRuns) { | |
List<User> users = generateUsers(dataSize); | |
System.out.printf("%nBenchmark for %,d users:%n", dataSize); | |
System.out.println("------------------------------------------------------"); | |
System.out.printf("%-20s %-20s %-20s %-20s%n", | |
"Run", "Default (μs)", "Pre-Sized (μs)", "Improvement (%)"); | |
long defaultTotal = 0; | |
long optimizedTotal = 0; | |
// Warmup runs | |
for (int i = 0; i < warmupRuns; i++) { | |
users.stream().map(User::getName).collect(Collectors.toList()); | |
users.stream().map(User::getName).collect(toExactList(users.size())); | |
} | |
// Measurement runs | |
for (int i = 0; i < measurementRuns; i++) { | |
long start = System.nanoTime(); | |
List<String> defaultList = users.stream() | |
.map(User::getName) | |
.collect(Collectors.toList()); | |
long defaultTime = System.nanoTime() - start; | |
start = System.nanoTime(); | |
List<String> exactList = users.stream() | |
.map(User::getName) | |
.collect(toExactList(users.size())); | |
long optimizedTime = System.nanoTime() - start; | |
if (!defaultList.equals(exactList)) { | |
throw new AssertionError("Results differ!"); | |
} | |
long defaultMicros = defaultTime / 1000; | |
long optimizedMicros = optimizedTime / 1000; | |
double improvement = (defaultMicros - optimizedMicros) * 100.0 / defaultMicros; | |
defaultTotal += defaultMicros; | |
optimizedTotal += optimizedMicros; | |
System.out.printf("%-20s %-20d %-20d %-20.2f%n", | |
"Run " + (i + 1), defaultMicros, optimizedMicros, improvement); | |
} | |
long defaultAvg = defaultTotal / measurementRuns; | |
long optimizedAvg = optimizedTotal / measurementRuns; | |
double totalImprovement = (defaultAvg - optimizedAvg) * 100.0 / defaultAvg; | |
System.out.println("------------------------------------------------------"); | |
System.out.printf("%-20s %-20s %-20s %-20s%n", | |
"Approach", "Avg Time (μs)", "Runs", "Speedup (%)"); | |
System.out.printf("%-20s %-20d %-20d %-20s%n", | |
"Default", defaultAvg, measurementRuns, "-"); | |
System.out.printf("%-20s %-20d %-20d %-20.2f%n", | |
"Pre-Sized", optimizedAvg, measurementRuns, totalImprovement); | |
} | |
public static void main(String[] args) { | |
int[] testSizes = {100_000, 1_000_000, 5_000_000, 10_000_000}; | |
System.out.println("Stream Collection Benchmark Results"); | |
System.out.println("=================================="); | |
System.out.println("Using Java " + System.getProperty("java.version")); | |
System.out.println("VM: " + System.getProperty("java.vm.name")); | |
for (int size : testSizes) { | |
runBenchmark(size, 5, 10); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Stream Collection Benchmark Results | |
================================== | |
Using Java 24.0.1 | |
VM: OpenJDK 64-Bit Server VM | |
Benchmark for 100,000 users: | |
------------------------------------------------------ | |
Run Default (μs) Pre-Sized (μs) Improvement (%) | |
Run 1 2351 1256 46.58 | |
Run 2 828 661 20.17 | |
Run 3 1002 561 44.01 | |
Run 4 852 570 33.10 | |
Run 5 688 583 15.26 | |
Run 6 678 547 19.32 | |
Run 7 641 537 16.22 | |
Run 8 784 564 28.06 | |
Run 9 803 566 29.51 | |
Run 10 728 555 23.76 | |
------------------------------------------------------ | |
Approach Avg Time (μs) Runs Speedup (%) | |
Default 935 10 - | |
Pre-Sized 640 10 31.55 | |
Benchmark for 1,000,000 users: | |
------------------------------------------------------ | |
Run Default (μs) Pre-Sized (μs) Improvement (%) | |
Run 1 10698 9209 13.92 | |
Run 2 10417 9264 11.07 | |
Run 3 261293 5813 97.78 | |
Run 4 6638 6159 7.22 | |
Run 5 5707 5331 6.59 | |
Run 6 5792 5398 6.80 | |
Run 7 5774 5362 7.14 | |
Run 8 5765 5317 7.77 | |
Run 9 5822 5285 9.22 | |
Run 10 5749 5273 8.28 | |
------------------------------------------------------ | |
Approach Avg Time (μs) Runs Speedup (%) | |
Default 32365 10 - | |
Pre-Sized 6241 10 80.72 | |
Benchmark for 5,000,000 users: | |
------------------------------------------------------ | |
Run Default (μs) Pre-Sized (μs) Improvement (%) | |
Run 1 98600 66014 33.05 | |
Run 2 98335 68020 30.83 | |
Run 3 97342 65658 32.55 | |
Run 4 71017 46826 34.06 | |
Run 5 51812 45027 13.10 | |
Run 6 77801 53943 30.67 | |
Run 7 74429 44422 40.32 | |
Run 8 52147 41154 21.08 | |
Run 9 56923 49915 12.31 | |
Run 10 76605 66296 13.46 | |
------------------------------------------------------ | |
Approach Avg Time (μs) Runs Speedup (%) | |
Default 75501 10 - | |
Pre-Sized 54727 10 27.51 | |
Benchmark for 10,000,000 users: | |
------------------------------------------------------ | |
Run Default (μs) Pre-Sized (μs) Improvement (%) | |
Run 1 176279 122505 30.51 | |
Run 2 177846 119907 32.58 | |
Run 3 160772 101778 36.69 | |
Run 4 168279 104449 37.93 | |
Run 5 170861 102189 40.19 | |
Run 6 253843 113624 55.24 | |
Run 7 177766 119461 32.80 | |
Run 8 187867 119753 36.26 | |
Run 9 233338 136025 41.70 | |
Run 10 260180 101669 60.92 | |
------------------------------------------------------ | |
Approach Avg Time (μs) Runs Speedup (%) | |
Default 196703 10 - | |
Pre-Sized 114136 10 41.98 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment