스트림 vs 조회수 vs 반복자


136

스칼라의 스트림, 뷰 (SeqView) 및 반복자의 차이점은 무엇입니까? 이것은 나의 이해이다 :

  • 그들은 모두 게으른 목록입니다.
  • 스트림은 값을 캐시합니다.
  • 반복자는 한 번만 사용할 수 있습니까? 처음으로 돌아가서 값을 다시 평가할 수 없습니까?
  • 뷰의 값은 캐시되지 않지만 계속해서 평가할 수 있습니까?

따라서 힙 공간을 절약하려면 반복자 (목록을 다시 탐색하지 않는 경우) 또는 뷰를 사용해야합니까? 감사.


7
나는 이것을 전에 대답했지만 어떻게 찾는가? 한숨 ...
다니엘 C. 소브랄

답변:


182

첫째, 모두 엄격하지 않습니다 . 그것은 함수와 관련된 특별한 수학적 의미를 가지고 있지만, 기본적으로 사전에 대신에 주문형으로 계산된다는 것을 의미합니다.

Stream실제로 게으른 목록입니다. 실제로, 스칼라에서 a StreamList누구 tail입니다 lazy val. 일단 계산되면 값은 계산 된 상태로 유지되고 재사용됩니다. 또는 말할 수 있듯이 값이 캐시됩니다.

Iterator단지 그것이 있기 때문에 한 번만 사용할 수 있습니다 탐색 포인터 모음으로, 그리고 자체 컬렉션입니다. 무엇 스칼라에서 특별하게 만드는 것은 당신이 같은 변환을 적용 할 수 있다는 사실 mapfilter단순히 새로운 얻을 Iterator당신이 다음 요소를 요청할 경우에만 이러한 변환을 적용 할를.

스칼라는 재설정 할 수있는 반복자를 제공했지만 일반적으로 지원하기가 매우 어렵고 버전 2.8.0을 만들지 않았습니다.

뷰는 데이터베이스 뷰와 매우 유사합니다. "가상"컬렉션을 생성하기 위해 컬렉션에 적용되는 일련의 변환입니다. 말씀 드린대로 모든 변환은 요소를 가져와야 할 때마다 다시 적용됩니다.

모두 Iterator와 뷰는 우수한 메모리 특성을 가지고있다. Stream훌륭하지만 스칼라에서 주요 이점은 무한 시퀀스 (특히 반복적으로 정의 된 시퀀스)를 작성하는 것입니다. 하나는 의 모두를 유지하지 않도록 Stream당신이 자신에 대한 참조를 유지하지 않는함으로써,하지만, 메모리 head(예를 들어, 사용하여 def대신 val을 정의하기 위해 Stream).

뷰에 의한 불이익으로 인해 일반적으로 force변환을 적용한 후 뷰의 전체 크기와 비교하여 페치 될 요소가 거의없는 경우 뷰로 유지해야합니다.


10
Iterator또한 무한을 프로빙하는 데 매우 편리하며 일반적으로 가능한 경우 스트림보다 선호합니다. 스트림의 실질적인 이점은 이전에 액세스 한 값이 캐시된다는 점인데, 이는 이전 값으로 정의 된 피보나치 시퀀스와 같은 것을 구현하려고 할 때 심각한 이점입니다.
Kevin Wright

5
피보나치 (Fibonacci)는 마지막 2 개의 이전 값만 필요하므로 전체 스트림을 유지하는 것은 낭비이므로 완벽한 예는 아닙니다. Ackermann 함수는 아마도 표준 예일 것입니다.
Jürgen Strobel

4
@ JürgenStrobel Ackermann은 스트림의 인덱스 액세스가 O (n)이므로 성능이 크게 저하됩니다. 그러나 나는 피보나치에 동의합니다.
Daniel C. Sobral

9
아 맞다. 이로 인해 Stream은 모든 캐싱 방식에 적합하지 않습니다.
Jürgen Strobel

7
이 답변은 매우 명확합니다. 문서의 일부 여야합니다 ... 아, 실제로 그렇습니다! 감사합니다 Daniel docs.scala-lang.org/tutorials/FAQ/stream-view-iterator.html
Svend
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.