2011-12-19 29 views
12

Come ho capito, Stream conserva gli elementi valutati di recente. Immagino che non mantenga gli elementi valutati tutti (non è fattibile), quindi probabilmente usa una "cache" interna.Scala stream e relativo utilizzo della memoria

E 'corretto? Posso controllare la dimensione e le politiche di questa cache?

+1

Non si dovrebbe pensare a 'Stream's come' Iterator's, ma piuttosto come 'List's la cui valutazione può essere ritardata. [Questa domanda e le sue risposte] (http://stackoverflow.com/questions/1527962/difference-between-iterator-and-stream-in-scala) possono aiutare. – Philippe

risposta

6

L'oggetto Stream conserva tutti i riferimenti che sono stati valutati/utilizzati fino a quel momento. Stream funziona come un List. Ogni elemento che può essere raggiunto da un riferimento tenuto e che è già stato visitato almeno una volta, non sarà raccolto.

Quindi in pratica i tuoi indicatori nel flusso e ciò che hai valutato finora definisce cosa verrà memorizzato nella cache.

+0

Quindi, 'stream' non ha una cache di memoria _limited_ per memorizzare i suoi elementi. Sembra un approccio molto dispendioso in termini di memoria ... – Michael

+1

Ecco perché non dovresti tenere un riferimento a nessun flusso. Definiscili sempre usando 'def'. Vedi anche http://stackoverflow.com/questions/12486762/scala-tail-recursive-stream-process-function-defined-in-trait-holds-reference e http://stackoverflow.com/questions/12529697/how- to-write-non-leaking-tail-recursive-function-using-stream-cons-in-scala – ron

12

Gli stream sono come elenchi che generano i membri in base alle esigenze. Una volta che un elemento è stato generato, viene mantenuto nello stream e riutilizzato.

Ad esempio:

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

vi darà un flusso di numeri naturali. Se chiamo

naturals(5) 

genererà elementi 0-5 e ritorno 5, se poi chiamo

naturals(8) 

Sarà riutilizzare i primi 6 elementi e generare più 3.

Se siete preoccupati per l'utilizzo della memoria, è possibile utilizzare Stream.drop(num) per produrre un nuovo flusso con num elementi rimossi dal principio, permettendo gli elementi troncati di essere garbage collection con il vecchio flusso. Ad esempio:

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

Tuttavia, finchè 'naturals' sta ancora puntando alla testa dello stream, quei primi cinque elementi non saranno spazzatura raccolto. –