본문 바로가기
Java

java Stream API는 for-loop보다 정말 느릴까?

by 에어컨조아 2022. 6. 15.

개인적으로 TDD 학습 공부를 하고 있었는데요!

해당 학습을 진행 하던 중 JAVA 8에서 제공하는 Stream에 대해서 학습하던 중 Stream이 for-loop보다 느리다라는 말을 들었습니다.

이때 나름의 이유는 있었지만 좀 더 명확하게 정리하고 싶어 글을 작성하였습니다.

우선 정말로 차이가 있는지 코드로 한번 알아보겠습니다.

for vs foreach vs Stream 성능 비교

image

1~100만을 더하여 성능을 측정해보았는데요! for의 성능이 foreach, Stream보다 더 나은 성능을 보여주는 것을 확인할 수 있었습니다.

그렇다면 Stream이 성능이 가장 안 좋은데 왜 사용해야 할까요?

🤔Stream API이 성능이 왜 가장 낮을까요?

어떠한 개념을 알기 위해서는 해당 개념이 왜 생겨났는지를 고민해보면 의외로 쉽게 정답을 찾을 수 있습니다.

Stream API은 JAVA 8부터 도입된 개념입니다. 여기서 말하는 Stream이란 데이터를 추상화 하여 다양한 방식으로 데이터를 가공하기 위해서 공통된 기능을 제공하는 것을 말합니다.

또한 Stream API개념이 들어온 후부터는 자바에서도 함수형 프로그래밍을 지원한다는 대표적인 사례 중 하나입니다. 그렇다면 우리는 여기서 함수형 프로그래밍에 조금 집중해볼 필요가 있습니다.

해당 주제에 너무 많이 벗어날 것 같아 함수형 프로그래밍의 가장 큰 특징인 불변성(Immutability)에 대해서 생각을 해보겠습니다. 불변성.. 말 그대로 변하지 않는 값을 말합니다.

즉 함수형 프로그래밍에서 말하는 함수는 순수함수(변하지 않는 함수)를 말합니다. 오직 매개변수로 들어온 값에 의존하여 리턴값을 반환합니다.

// 순수함수가 아닌 예
private String name = "홍길동";
public String getName() {
        return name + "입니다.";
}

// 순수함수
public String getName(String name){
        return name + "입니다.";
}

그렇다면 불변성을 지키기 위해 가장 쉬운 방법이 무엇일까요? 바로 복사입니다.

따라서 JAVA에서 제공하는 Stream API는 매개변수를 통한 값 복사를 통해 불변성을 지원하기 때문에 메모리 증가, 복사로 인한 오버헤드 등으로 속도가 느릴 수 밖에 없습니다.

또한 Stream의 역사보다 for-loop의 역사가 더 오래되었습니다. 약 40년이나 더 오래되었다고 하는데요! 역사가 깊다는 말은 그만큼 안정성과 컴파일러 최적화가 잘되어 있다는 것을 말합니다.

그렇다면 왜 스트림을 사용해야지?🙄

JAVA 8에서 Stream API가 추가되면서 JAVA 개발자들은 열광했는데요!
대표적인 이유 중 하나가 가독성입니다.
예를들어 User 클래스에서 나이가 19살 이상인 User들을 뽑으려고 할 때의 차이를 한번 보겠습니다.

// for loop 사용
List<User> adults = new ArrayList<>();
int size = users.size();
for(int i = 0; i < size; i++) {
        User user = users.get(i);
        if(user.getAge() >= 19){
                adults.add(user);
        }
}

// Stream API 사용
users.stream()
         .filter(user -> user.getAge() >= 19)
         .collect(Collectors.toList());

또한 앞서 살펴본 불변성도 한 몫 하는데요!
불변성을 지원함에 따라 원천적으로 멀티 스레드 환경일때 데이터 원자성(Atomic)을 보장하여 이에따른 side effect가 발생하는 것을 방지합니다.

개인적으로 이 2개의 특징만으로도 충분히 스트림을 사용하는 것에 매력을 느끼기엔 충분하다 생각하는데요! 혹시라도 다른 의견이나 고민한 부분들이 있으시다면 언제든 댓글 부탁드립니다🙏

Reference

https://blogs.oracle.com/javamagazine/post/java-parallel-streams-performance-benchmark
https://jaxenter.com/java-performance-tutorial-how-fast-are-the-java-8-streams-118830.html
https://jypthemiracle.medium.com/java-stream-api는-왜-for-loop보다-느릴까-50dec4b9974b
https://gsmesie692.tistory.com/267

댓글