2011-12-19 9 views
12

Jak rozumiem, Stream zachowuje ostatnio ocenione elementy. Domyślam się, że nie zachowuje on wszystkich ocenianych elementów (nie jest to możliwe), więc prawdopodobnie używa pewnej wewnętrznej "pamięci podręcznej".Strumienie Scala i ich wykorzystanie pamięci

Czy to prawda? Czy mogę kontrolować rozmiar i zasady tej pamięci podręcznej?

+1

Nie powinieneś myśleć o 'Stream's jako' Iteratorze', ale raczej o 'List'', którego ocena może być opóźniona. [To pytanie i jego odpowiedzi] (http://stackoverflow.com/questions/1527962/difference-between-iterator-and-stream-in-scala) może pomóc. – Philippe

Odpowiedz

6

Obiekt strumienia zachowuje wszystkie odwołania, które zostały ocenione/dostępne do tej pory. Stream działa jak List. Każdy element, do którego można dotrzeć z posiadanego odniesienia, i który był już dostępny co najmniej raz, nie będzie zbierany śmieci.

Tak więc Twoje wskaźniki w strumieniu i to, co dotąd oceniłeś, określają, co zostanie zbuforowane.

+0

Tak więc 'stream' nie ma pamięci podręcznej _limited _ do przechowywania jej elementów. Brzmi jak bardzo pochłaniające pamięć podejście ... – Michael

+1

Dlatego powinieneś zawsze mieć referencje do dowolnych strumieni. Zawsze definiuj je za pomocą 'def'. Zobacz także http://stackoverflow.com/questions/12486762/scala-tail-recursive-stream-processor-function-defined-in-t-hold-holds-reference i http://stackoverflow.com/questions/12529697/how- to-write-non-leaking-tail-recursive-function-using-stream-cons-in-scala – ron

12

Strumienie są jak listy, które generują swoich członków, ponieważ są wymagane. Po wygenerowaniu elementu zostaje on zachowany w strumieniu i ponownie wykorzystany.

Na przykład:

lazy val naturals: Stream[Int] = Stream.cons(0, naturals.map{_ + 1}) 

daje strumień liczb naturalnych. Jeśli zgłoszę

naturals(5) 

generuje elementów 0-5 i powrotu 5, jeśli następnie wywołać

naturals(8) 

To ponowne 6 pierwszych elementów i wygenerować trzy inne.

Jeśli chodzi o zużycie pamięci, można użyć Stream.drop(num) produkować nowy strumień z usuniętymi elementami num od początku, dzięki czemu elementy ścięte być zbierane śmieci ze starego strumienia. Na przykład:

naturals(5) //returns 5 
val truncated = naturals.drop(4) 
truncated(5) //returns 9 
+6

Jednak dopóki 'naturals' nadal wskazuje na nagłówek strumienia, te pierwsze pięć elementów nie będzie odpadami Zebrane. –