본문 바로가기

TroubleShooting/Java

java 8 stream API 실행시간 비교

728x90

 java 8 에 포함된 stream 을 사용해서 foreach 문과 비교해서 수행 시간이 얼마나 차이 나는지 비교를 해보았다.

※ 환경은 i7-4790 3.6GHz, 16GB, 윈도우 머신에서 테스트했다.

30 만개의 랜덤한 수열에서 (i % 2) == 0 조건을 만족하는 숫자들의 갯수을 구해보았다.

    @Test
    public void streamExecutionTimeTest() {
        List<Integer> list = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < 300000; i++) {
            list.add(random.nextInt());
        }

        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        System.out.println(list.pallelStream()
                .filter(x -> (x % 2 == 0))
                .count());
        stopWatch.stop();
        System.out.println("parallel filter elapsed : " + stopWatch.getTotalTimeMillis());

        stopWatch.start();
        System.out.println(list.stream()
                .filter(x -> (x % 2 == 0))
                .count());
        stopWatch.stop();
        System.out.println("filter elapsed : " + stopWatch.getTotalTimeMillis());

        int count = 0;
        stopWatch.start();
        for (int i : list) {
            if (i % 2 == 0)
                count++;
        }
        System.out.println(count);
        stopWatch.stop();
        System.out.println("foreach filter elapsed : " + stopWatch.getTotalTimeMillis());
    }

실행결과

150075
parallel filter elapsed : 23
150075
filter elapsed : 32
150075
foreach filter elapsed : 50

테스트 코드를 실행할때마다 결과값이 틀려지겠지만, 병렬 스트림(parallel stream) 이나 스트림 방식이 미세하지만 foreach 문보다 빠르게 나온다.(단위는 ms 이다)

30 만개의 랜덤한 수열에서 최소값을 구해보았다.

    stopWatch.start();
    System.out.println(list.stream().parallel().min(Comparator.comparing(Integer::valueOf)).get());
    stopWatch.stop();
    System.out.println("parallel min elapsed : " + stopWatch.getTotalTimeMillis());

    stopWatch.start();
    System.out.println(list.stream().min(Comparator.comparing(Integer::valueOf)).get());
    stopWatch.stop();
    System.out.println("stream min elapsed : " + stopWatch.getTotalTimeMillis());

    int min = 0;
    stopWatch.start();
    for (int i : list) {
        if (i < min)
            min = i;
    }
    System.out.println(min);
    stopWatch.stop();
    System.out.println("foreach min elapsed : " + stopWatch.getTotalTimeMillis());

실행 결과

-2147470607
parallel min elapsed : 72
-2147470607
stream min elapsed : 89
-2147470607
foreach min elapsed : 101

if 조건문이 약간 달라졌지만, 그래도 foreach 문보다는 스트림(병렬 스트림) 방식이 조금 빨라진걸 볼 수 있다.

30 만개의 랜덤한 수열의 총합을 구해보았다.

    stopWatch.start();
    System.out.println(list.stream().mapToInt(i -> i.intValue()).sum());
    stopWatch.stop();
    System.out.println("stream sum elapsed : " + stopWatch.getTotalTimeMillis());

    int sum = 0;
    stopWatch.start();
    for (int i : list) {
        sum += i;
    }
    System.out.println(sum);
    stopWatch.stop();
    System.out.println("foreach sum elapsed : " + stopWatch.getTotalTimeMillis());

실행 결과

281342850
stream sum elapsed : 108
281342850
foreach sum elapsed : 117

sum() 에서는 테스트를 여러번 해봐도 스트림이 빠르게 나오기는 한데, 큰 차이가 안나왔다.

stream 은 코드 사용에 익숙해지면 람다도 활용할 수 있어서 분명 장점을 가진다. 처리 속도도 데이터가 많을수록 기존 for 문 또는 foreach 문 방식보다는 빠르게 처리할 수 있는거 같다.