0

I have a very simple program

package t;
public class T {

    public static void main(String[] args) {
        for (int i =0; i<10; i++) {
            java.util.List<Character> l = java.util.Arrays.asList('1', '2', 'a', 'b', '3', '4', 'p');
            java.time.Instant then = java.time.Instant.now();
            java.util.List<Character> numbers1 = l.stream().filter(Character::isDigit).collect(java.util.stream.Collectors.toList());
            long streamTime = java.time.Duration.between(then, java.time.Instant.now()).toNanos();
            then = java.time.Instant.now();
            java.util.List<Character> numbers = new java.util.ArrayList<>();
            for (Character c : l) {
                if (Character.isDigit(c)) {
                    numbers.add(c);
                }
            }
            long forLoopTime = java.time.Duration.between(then, java.time.Instant.now()).toNanos();
            System.out.println(numbers + " For Time taken " + forLoopTime + " Stream Time " + streamTime);
        }
    }
}

When executed in Java 8 following is the o/p

java t/T

[1, 2, 3, 4] For Time taken 0 Stream Time 54000000
[1, 2, 3, 4] For Time taken 0 Stream Time 0
[1, 2, 3, 4] For Time taken 0 Stream Time 0
[1, 2, 3, 4] For Time taken 0 Stream Time 0
[1, 2, 3, 4] For Time taken 0 Stream Time 0
[1, 2, 3, 4] For Time taken 0 Stream Time 0
[1, 2, 3, 4] For Time taken 1000000 Stream Time 0
[1, 2, 3, 4] For Time taken 0 Stream Time 0
[1, 2, 3, 4] For Time taken 0 Stream Time 0
[1, 2, 3, 4] For Time taken 0 Stream Time 0

Same executed in java 16

java t/T.java

[1, 2, 3, 4] For Time taken 37000 Stream Time 701000
[1, 2, 3, 4] For Time taken 6000 Stream Time 31000
[1, 2, 3, 4] For Time taken 6000 Stream Time 12000
[1, 2, 3, 4] For Time taken 5000 Stream Time 11000
[1, 2, 3, 4] For Time taken 5000 Stream Time 12000
[1, 2, 3, 4] For Time taken 7000 Stream Time 19000
[1, 2, 3, 4] For Time taken 6000 Stream Time 18000
[1, 2, 3, 4] For Time taken 7000 Stream Time 18000
[1, 2, 3, 4] For Time taken 7000 Stream Time 14000
[1, 2, 3, 4] For Time taken 6000 Stream Time 20000

When executed in java 11

java t/T.java

[1, 2, 3, 4] For Time taken 40000 Stream Time 461000
[1, 2, 3, 4] For Time taken 7000 Stream Time 39000
[1, 2, 3, 4] For Time taken 5000 Stream Time 17000
[1, 2, 3, 4] For Time taken 10000 Stream Time 20000
[1, 2, 3, 4] For Time taken 9000 Stream Time 33000
[1, 2, 3, 4] For Time taken 8000 Stream Time 22000
[1, 2, 3, 4] For Time taken 8000 Stream Time 36000
[1, 2, 3, 4] For Time taken 6000 Stream Time 17000
[1, 2, 3, 4] For Time taken 6000 Stream Time 14000
[1, 2, 3, 4] For Time taken 5000 Stream Time 22000

This indicates that no matter which version of JDK we use streams are slower than basic for loop. Is my understanding correct? I was under the impression that JDK 8 it may have been slower but not in higher versions of JDK.

  • 3
    I'm afraid, this doesn't conclusively indicate anything. It is a flawed benchmark. Please read https://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java – Stephen C Jun 23 '21 at 06:03
  • 2
    So your benchmark consists in running *one* loop, over a *tiny* sample? Meh. –  Jun 23 '21 at 06:03
  • 2
    As the other comments indicate, you're not measuring what you think you are measuring. And, even if you were, it probably doesn't matter, either; it is unlikely that this is the difference between meeting or missing your performance requirements, or that the supposed additional costs of running this code for a million years exceeds the value of the time you've already spent worrying about it. Unless you have a global sense of where your resources are going, obsessing over hard-to-measure micro-performance issues doesn't make sense. – Brian Goetz Jun 23 '21 at 15:22

0 Answers0