티스토리 뷰
https://pamyferret.tistory.com/43
지난번에 Java 8부터 지원하는 Stream API에 대해 포스팅을 했었다.
모든 데이터를 다룰 때 사용하면 좋다고 포스팅을 했었는데 그렇다면 Stream API가 무조건 좋을까?
for문을 사용했을 때와 Stream API를 사용했을 때의 성능 차이
Stream API에 forEach가 있어서 for문이랑 Stream API의 성능은 많이 비교된다.
그래서 나도 간단하게 코드를 짜서 해봤다. 물론 이 코드에서 for문과 Stream API는 완전히 똑같은 조건이라고 볼 수는 없다.
(Stream API를 이용해서는 collect()를 이용해서 아예 새로운 List를 생성하므로...)
List<Integer> l = createIntList(100000);
long startTime = System.nanoTime();
for(int i = 0; i < l.size(); i++) {
l.set(i, l.get(i) + 1);
}
long endTime = System.nanoTime();
System.out.println(String.format("for-loop: %dns", endTime - startTime));
startTime = System.nanoTime();
l = l.stream().map(n -> n--).collect(Collectors.toList());
endTime = System.nanoTime();
System.out.println(String.format("Stream: %dns", endTime - startTime));
일부러 차이를 명확하게 보려고 milli seconde가 아닌 nano seconde로 걸리는 시간을 출력해봤다.
결과는 실행할 때마다 다르긴 하지만 대략 그 중 하나를 뽑아보면 아래와 같다.
// 10 size로 테스트
for-loop: 13455ns
Stream: 55508377ns
// 100 size로 테스트
for-loop: 72114ns
Stream: 57743007ns
// 100000 size로 테스트
for-loop: 10447214ns
Stream: 72403508ns
매 번 결과가 조금씩 차이가 나긴 하지만 한 가지 달라지지 않는 것은 for문이 stream을 사용했을 때보다 배로 빠르다는 것이다.
어디서는 데이터가 적으면 별로 차이가 안 난다고 해서 10 size의 List로도 테스트를 해봤지만 stream().collect()를 사용해서 그런지 데이터가 작다고 그렇게 크게 차이가 나지 않았다.
왜 for문이 Stream보다 빠를까?
이 부분은 여러 가지 이유가 있을 수 있겠지만 여기저기 찾아본 결과 아래 2가지로 인해 for문이 stream보다 빠르다는 것을 알 수 있었다.
1. for문은 단순 인덱스 기반이다.
for문은 단순 인덱스 기반으로 도는 반복문으로 메모리 접근이기 때문에 Stream에 비해 빠르고 오버헤드도 없다.
stream의 경우는 JVM이 이것저것 처리해줘야하는 것들이 많아 실행 시 느릴 수 밖에 없다.
2. for문은 컴파일러가 최적화를 시킨다.
stream은 java 8부터 지원한 것이고 for문은 그보다 훨씬 오래전부터 계속 사용해왔다.
그만큼 사용되는 컴파일러는 오래 사용된 for문에 대한 처리가 되어 있어 for문의 경우 미리 최적화를 시킬 수 있지만,
stream의 경우 신생(?)인 만큼 정보가 없어 for문과 같은 정교한 최적화를 수행할 수 없다.
그렇다면 왜 Stream을 사용하는건가?
이것은 결국 개발자 역량에 달린 문제이지만 굳이 몇 가지를 꼽자면 아래와 같다.
1. 가독성이 좋아진다.
이것도 개발자 역량에 따라 다르지만 stream을 사용하면 확실히 stream api에 포함되어 있는 여러 함수 들을 이용해 코드가 간결해진다.
물론 이것도 stream에 익숙하지 않은 사람은 그 의미를 일일이 해독하느라 코드를 읽는 시간디 더 걸릴 수 있지만,
stream을 한 두 번 보다보면 가독성이 좋다는 것이 느껴진다.
물론 이것도 무조건적인 장점은 아니다. 어떤 기능을 개발하느냐에 따라 for문이 가독성이 좋을 수 있고(특히 for문 안에서 중첩 반복 또는 조건문을 사용하는 경우) stream이 오히려 가독성이 안 좋을 수 있다.
2. 코드로 작성해야하는 로직을 stream에서 제공해주는 함수로 간단하게 해결 가능하다.
이것은 특히 filter, reduce 등과 같이 단순 forEach가 아닌 함수들을 사용할 경우 유용하다.
데이터가 많지 않을 경우 stream을 사용해도 (for문보다 성능이 떨어지지만) 속도가 느리지 않다.
그러니 코드로 일일이 기능을 구현해야하는 것들을 stream api에서 제공한다면 당연히 stream을 사용하든 것이 좋다.
단, 단순 forEach일 경우 stream이 아닌 for문을 사용하자! (또는 컬렉션의 forEach 함수를!)
개발에 대해 공부를 하면 할수록 이게 저것보다 좋다!! 라는 것도 찾지만 개발하는 상황에 따라 좋을 수도 나쁠 수도 있는 것을 많이 마주한다.
결국 어떤게 좋은 것인지 알고 사용하는 것은 개발 경험과 여러 가지 시도가 중요한 것 같다.
'Java' 카테고리의 다른 글
ThreadLocal이란? (0) | 2021.12.30 |
---|---|
ConstraintValidator로 컨트롤러에서 받는 값 유효성 체크하기 (0) | 2021.10.14 |
Checked Exception vs UnChecked Exception (0) | 2021.10.12 |
custom annotation(커스텀 어노테이션) 만들기 (0) | 2021.10.08 |
빈 문자도 에러 없이 숫자로 형변환 하기 (0) | 2021.10.07 |
- Total
- Today
- Yesterday
- springboot
- Intellij
- PostgreSQL
- HttpClient
- 캐시
- 캐싱
- postgres
- MAC
- Spring
- mockito
- 이클립스
- 역직렬화
- 공간데이터
- DB
- 자바
- annotation
- enum
- rabbitmq
- 스프링부트
- Caching
- eclipse
- JPA
- ssh
- 어노테이션
- DATABASE
- k8s
- Java
- 메시지큐
- cache
- 데이터베이스
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |