I have the following class:
public final class App {
private App() {
}
public static void main(String[] args) {
Stopwatch stopwatch = Stopwatch.createStarted();
new App().main();
System.out.println(((double) stopwatch.elapsed(TimeUnit.MICROSECONDS) * 1_000_000) + " seconds!");
}
private void main() {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
list.add(ThreadLocalRandom.current().nextInt(1000));
}
System.out.println(minNoUnboxing(list));
System.out.println(minWithUnboxing(list));
}
private Integer minNoUnboxing(List<Integer> list) {
return list.stream().min(Integer::compareTo).orElse(-1);
}
private Integer minWithUnboxing(List<Integer> list) {
return list.stream().mapToInt(x -> x).min().orElse(-1);
}
}
This class has 2 methods that take a list of integers and return the smallest number. One way to do it is to pass Integer's compareTo() method as a comparator in the min() function. The other way to do it is to get an IntStream from the list and call the min() function on that.
The second way uses unboxing to map the wrapped ints. Unboxing is famous for being slow when used frequently, but I could not see the difference between using and not using it in this program.
Which way is faster? Or maybe they are both the same?
Thanks.
EDIT:
I took Code-Apprentice's advice and did a bunch of measurements using this approach:
Stopwatch noUnboxing = Stopwatch.createStarted();
for (int i = 0; i < 1000; i++) {
minNoUnboxing(list);
}
System.out.println((double) noUnboxing.elapsed(TimeUnit.MILLISECONDS) / 1000 + " no unboxing seconds");
Stopwatch withUnboxing = Stopwatch.createStarted();
for (int i = 0; i < 1000; i++) {
minWithUnboxing(list);
}
System.out.println((double) withUnboxing.elapsed(TimeUnit.MILLISECONDS) / 1000 + " with unboxing seconds");
And it turns out that unboxing is actually 2x faster than the first way. Why is that?
Output:
4.166 no unboxing seconds
1.922 with unboxing seconds