Stream (Java Platform SE 8 )

A sequence of elements supporting sequential and parallel aggregate operations. The following example illustrates an aggregate operation using Stream and IntStream: int sum = widgets.stream() .filter(w -> w.getColor() == RED) .mapToInt(w -> w.getWeight())

docs.oracle.com

들어가는 말

나는 전 프로젝트에서 사수가 stream을 너무 좋아했다. 그래서 단순 for-loop도 stream의 foreach로 프로그래밍을 했다. 나도 stream이 적응하고 익숙해지니 stream이 그냥 for문을 쓰는 것보다 간지가나고 편해졌다. 하지만 의문이 들었다. 내가 stream을 무작정 쓰고 있는데 누군가 나에게 "너는 왜 stream만 쓰세요?" 라고 물어보면 답변을 못해줄거 같아서 공부고 그 내용을 적어볼 것이다.

 

 

검색했을 때...

"java stream for-loop" 라는 키워드로 검색했을 때 stream과 for-loop의 비교내용은 아래와 같다.

- for, foreach

  • 구체적인 로직이 외부에 노출되는 외부 반복의 형태입니다.
  • for문은 java 1, foreach문은 java 5부터 등장했습니다.
  • foreach문은 컴파일 시 for문으로 변환됩니다.

- stream

  • 구체적인 로직이 외부에 노출되지 않는 내부 반복의 형태입니다.
  • 함수형 프로그래밍 패러다임이 도입된 java 8부터 등장했습니다.

- 차이

  1.  for-loop가 Stream 보다 빠르다.
  2. Stream을 쓰면 코드가 간결해진다.
  3. Stream을 쓰면 연계기(filter, map 등)을 사용할수 있다.
  4. Stream은 디버깅하기가 힘들다.
  5. Stream은 병렬처리가 쉽다.
이것만 놓고 보면 stream을 장점이 월등하기 좋지만 성능은 for-loop가 좋다고한다.  그렇다면 성능이 좋은 for-loop만 쓰는 것이 장땡아닌가 생각도 든다. 그렇다면 for-loop로도 다 처리할 수 있는데 stream은 왜 생긴거지 라는 의문이 들었다. 그러면 내가 신나게 stream을 쓰고 있는데 누군가 이러면 성능이 안좋지 않냐? 라고하면 나는 죄인이 되는 것이다.

 

 

 

 

나의 stream 사용법

나는 누군가가 Stream을 굳이 사용하는 이유를 묻는다면 아래와 같이 답변을 해줄 것이다. 그리고 나의 프로그래밍의 stream과 for-loop의 규칙을 두었다. 

나는 현대개발은 변경에 강하도록 가독성을 올리고 비용을 더 들이는 것이 낫다고 생각한다. 그리고  일부 최적화된 성능이 필요하면  for문을 사용한다.

- stream의 대한 나의 규칙

  1. 단순하게 Array의 모든 length를 읽는 경우는 for-loop를 사용한다. 
  2. 데이터 가공(filter, map 등)을 해야하면 stream을 사용한다.
  3. 성능이 중요한 기능이라면 for-loop를 사용한다.
  4. 데이터가 많고 순회비용이 계산비용보다 높다고 판단되면 steam을 사용한다. (ex.  ArrayList)
 ArrayList에서 모든 원소를 순회하는 데 걸리는 시간 복잡도는 O(n)이다. wrapped type은 primitive type과 달리 stack이 아닌 heap 메모리 영역에 저장된다.

JVM 상에서 Heap Memory에 저장되는 간접 참조는 힙에 객체의 내용이 있다면 중간에 그곳을 가리키는 메모리 영역이 있고(핸들 메모리) 스택에 있는 변수가 핸들 메모리를 참조해서 실제 힙의 주소를 얻은 후 힙의 실제 내용을 참조하게 되는 방식이다. 반면, JVM 상에서 Stack Memory에 저장되는 직접 참조의 경우 스택에 있는 변수가 힙 메모리의 실제 주소를 가지고 있어 직접 참조 하게 되는 방식이다. 
그러므로 자주 참조되는 변수나 객체가 있다면 직접 참조 방식이 훨씬 뛰어난 성능을 보인다.

 

 

 

 

 

읽어보면 좋은 블로그 

 

Java Stream API는 왜 for-loop보다 느릴까?

The Korean Commentary on ‘The Performance Model of Streams in Java 8" by Angelika Langer

jypthemiracle.medium.com

 

자바8 Streams API 를 다룰때 실수하기 쉬운것 10가지

이 글은 자바 8 Stream API 를 아는 사람이 주의해야 할 것에 대해 쓰여진 글이지만 , 몰라도 상관없습니다. 이 글 읽어보면 대충 이런거구나 알 수 있으니깐요. Java 8 Stream API 을 배워야하는 이유로

hamait.tistory.com

복사했습니다!