2009-08-30 9 views
5

L'esecuzione del ritardo è quasi sempre un vantaggio. Ma poi ci sono casi in cui è un problema e si ricorre a "fetch" (in Nhibernate) per farglielo prendere.Quando la valutazione lazy non è utile?

Conoscete situazioni pratiche in cui la valutazione pigra può azzannarvi ...?

risposta

0

Le risorse di caricamento lente implicano un viaggio avanti e indietro tra il richiedente e la sorgente per ogni carico. Nel caso di NHibernate, ciò significa un dall'applicazione al database (che è spesso su un server diverso).

C'è spesso un sovraccarico associato a ogni viaggio (c'è sicuramente per NHibernate o qualsiasi altra query DB).

Se si sa che avrete bisogno di tutti o di una parte sostanziale dei dati, è meglio tirarli in una volta sola e incorrere nel sovraccarico solo una volta.

Un esempio classico è quando è necessario richiamare un elenco di oggetti per compilare una casella combinata (spesso questi saranno oggetti di configurazione). Il caricamento lento tornerebbe al database ogni volta che è stato aggiunto un membro della lista alla casella combinata. Dal momento che stai mettendo l'intera lista nella casella combinata, dovrai sostenere un sacco di overhead extra per recuperare ogni oggetto.

0

Può anche essere un problema con l'esperienza dell'utente del programma. Le persone attenderanno con piacere per 5 secondi quando un banner viene visualizzato sullo schermo durante il caricamento delle app, ma si disinteressano di dover aspettare 0,25 secondi quando stanno digitando qualcosa in una casella di testo. Se la quantità di tempo necessaria per caricare tutti i tuoi dati con entusiasmo non è così lunga, potresti considerare di farlo a un certo punto nel flusso di lavoro in cui le persone accettano un ritardo (come il caricamento delle app, la finestra pop-up, la pressione dei pulsanti).

3

La valutazione lenta non è utile in situazioni in cui la prestazione è critica e un valore deve essere sempre da valutare. In questi casi è meglio valutare solo il valore e portarlo a termine, perché il sovraccarico della valutazione pigra sarà sprecato.

+0

valutazione pigro è un modo per ottenere le prestazioni. – Zorf

+5

errato. Se è necessario valutare la risposta, l'overhead aggiuntivo per la valutazione lazy crea un costo senza alcun beneficio. – vy32

+0

vy32 è corretto. Ad esempio, se si dispone di un elenco di oggetti visualizzati in un elenco su un dispositivo mobile, la vista verrà creata nel momento in cui gli elementi dell'elenco vengono visualizzati sullo schermo. Se alcuni valori mostrati nell'elenco devono essere caricati in modo pigro, l'elenco risulterà rallentato perché i nuovi listi non possono essere riempiti abbastanza velocemente. – Janusz

0

La valutazione lenta non è utile quando non si desidera memorizzare il valore, basta usarlo. Ma questo dipende dall'implementazione del valutatore pigro. Alcuni sistemi (come Haskell) possono dire se un valore sarà usato di nuovo. Alcuni altri non possono e possono causare perdite.

2

La valutazione lenta non è utile quando la valutazione può avere effetti collaterali. Questa è l'unica ragione ed è per questo che solo lingue puramente funzionali ce l'hanno. Se le espressioni possono avere effetti collaterali che devono verificarsi in un certo ordine non puoi averle.

Oltre a ciò, la valutazione lenta guadagna solo le prestazioni, questo è l'obiettivo principale. Ed è per questo che alcune lingue proibiscono effetti collaterali, per ottenere una valutazione pigra per quel compromesso, un altro buon effetto è che le strutture di controllo possono essere funzioni regolari.

2

Un esempio per pigrizia causare problemi strani (che mi è successo oggi, in Haskell):

import System.IO 

main = do 
    content <- readFile "foo.txt" 
    writeFile "foo.txt" content 

Questo getta il seguente errore durante la compilazione & giustiziati:

foo.txt: openFile: resource busy (file is locked) 

Quello che ho pensato che sarebbe do: Apri il file foo.txt, leggi il contenuto, chiudi di nuovo. Quindi aprilo per scrivere, scrivi il contenuto e chiudilo di nuovo.

Che cosa ha effettivamente fatto: "Ah, un po 'di contenuto, probabilmente lo leggerò più tardi quando ne avremo davvero bisogno." Quindi apri "foo.txt" per scrivere. Inizia a scrivere contenuti ... ok, ora abbiamo bisogno del contenuto. Apri foo.txt per la lettura - bam!

So che è semplice da risolvere, ma è difficile da trovare se non si sa dove guardare.

+1

Questo è un problema causato specificamente dall'I/O pigro, piuttosto che dalla valutazione pigra in generale. Lazy I/O è in realtà piuttosto pericoloso e contro lo spirito della programmazione funzionale, in quanto fornisce effetti collaterali a funzioni che dovrebbero essere pure (vale a dire, la valutazione di una stringa fa sì che i dati vengano letti dal disco - un effetto collaterale!), Portando a problemi come questo, e anche questo: http://stackoverflow.com/questions/2981582/haskell-lazy-io-and-closing-files Ma si può certamente avere una valutazione lenta senza I/O pigro, infatti, tale sembra essere l'attuale direzione di Haskell. – Jesse

+0

Questo è un esempio accurato! – vy32

4

Non è possibile eseguire una riduzione (ad esempio una piega) sui dati di input in uno spazio costante con una valutazione lenta, poiché la valutazione ritardata di ciascun gradino di riduzione determina una complessità dello spazio lineare. È invece necessario valutare la forza del risultato di ogni fase di riduzione per mantenere costante l'utilizzo dello spazio.

Ad esempio, hashing di un file in Haskell. Potresti avere un buon significato e leggere il file di input pigramente pezzo dopo pezzo, aggiungendo ogni pezzo al digest, ma dietro la tua schiena Haskell sta in realtà facendo un thunk per ogni chunk che aggiungi al digest, lasciando l'intero file in memoria in questi thunks fino a quando il digest risultante viene effettivamente valutato. Ahia!

vedi ultima commento qui: Haskell lazy I/O and closing files