2009-08-30 28 views
5

Opóźnienie wykonania jest prawie zawsze dobrodziejstwem. Ale są też przypadki, gdy jest to problem i uciekasz się do "pobierania" (w Nhibernate), aby szybko go pobrać.Kiedy leniwa ocena nie jest przydatna?

Czy znasz praktyczne sytuacje, w których leniwe oceny mogą Cię ugryźć ...?

Odpowiedz

0

Leniwe zasoby ładunkowe wymagają podróży w obie strony między zleceniodawcą i źródłem dla każdego ładunku. W przypadku NHibernate oznacza to od aplikacji do bazy danych (która często znajduje się na innym serwerze).

Z każdą podróżą wiąże się często obciążenie (na pewno jest dla NHibernate lub innego zapytania DB).

Jeśli wiesz, że będziesz potrzebować wszystkich lub znacznej części danych, lepiej jest jechać jednym ruchem i ponosić tylko jednorazowy narzut.

Klasycznym przykładem jest sytuacja, w której trzeba cofnąć listę obiektów, aby wypełnić pole kombi (często będą to obiekty konfiguracyjne). Leniwe ładowanie będzie wracać do bazy danych za każdym razem, gdy dodasz członka listy do pola kombi. Ponieważ umieszczasz całą listę w polu kombi, możesz ponieść wiele dodatkowych kosztów, aby leniwy pobrać każdy obiekt.

0

Może to być również problem z doświadczeniem użytkownika w programie. Ludzie będą szczęśliwie czekać 5 sekund, gdy baner jest wyświetlany na ekranie podczas ładowania aplikacji, ale pogardzają, że muszą czekać 0,25 sekundy, gdy wpisują coś w polu tekstowym. Jeśli ilość czasu potrzebnego na załadowanie wszystkich danych nie jest zbyt długa, możesz rozważyć zrobienie tego w pewnym momencie przepływu pracy, w którym ludzie akceptują opóźnienie (takie jak załadowanie aplikacji, wyskakujące okno, naciśnięcie przycisku).

3

Leniwa ocena nie jest przydatna w sytuacjach, w których wydajność jest krytyczna, a wartość musi być zawsze oceniona na zawsze. W takich wypadkach lepiej jest oceniać wartość i robić z nią, ponieważ obciążenie związane z leniwą oceną zostanie zmarnowane.

+0

ocena Lazy jest sposobem na uzyskanie wydajności. – Zorf

+5

Niepoprawnie. Jeśli musisz ocenić odpowiedź, dodatkowy koszt dla leniwego oszacowania tworzy koszt bez korzyści. – vy32

+0

vy32 jest poprawny. Na przykład, jeśli masz listę obiektów wyświetlanych na liście na urządzeniu mobilnym, widok zostanie utworzony w momencie, gdy elementy listy pojawią się na ekranie. Jeśli niektóre wartości, które są wyświetlane na liście, muszą być leniwy, lista będzie się zacinać i opóźniać, ponieważ nowe listy nie mogą być wystarczająco szybko wypełnione. – Janusz

0

Leniwa ocena nie jest przydatna, gdy nie chcesz przechowywać wartości, po prostu z niej skorzystaj. Ale to zależy od wdrożenia leniwego oceniającego. Niektóre systemy (takie jak Haskell) mogą stwierdzić, czy wartość zostanie ponownie użyta. Niektóre inne nie mogą i mogą powodować nieszczelności.

2

Leniwa ocena nie jest przydatna, gdy ocena może mieć efekty uboczne. Jest to jedyny powód i dlatego używają go wyłącznie języki funkcjonalne. Jeśli wyrażenia mogą mieć efekty uboczne, które muszą wystąpić w określonej kolejności, nie możesz tego zrobić.

Poza tym leniwy ewaluacja tylko zyskuje wydajność, to jest jej główny cel. I dlatego niektóre języki zabraniają efektów ubocznych, aby uzyskać leniwą ocenę tego kompromisu, innym dobrym skutkiem tego jest to, że struktury kontrolne mogą być regularnymi funkcjami.

2

Jednym z przykładów lazyness powodując dziwne problemy (zdarzyło mi się dzisiaj, w Haskell):

import System.IO 

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

ten wyrzuca następujący błąd podczas skompilowane & wykonywany:

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

Co Myślałem, że będzie wykonaj: Otwórz plik foo.txt, przeczytaj zawartość, zamknij ponownie. Następnie otwórz go do pisania, zapisz treść i zamknij ponownie.

Co to właściwie zrobiło: "Ah, niektóre treści, prawdopodobnie przeczytam to później, kiedy będziemy tego potrzebować." Następnie otwórz "foo.txt" do pisania. Zacznij pisać treść ... ok, teraz potrzebujemy treści. Otwórz foo.txt do czytania - bam!

Wiem, że naprawienie jest trywialne, ale trudno je znaleźć, jeśli nie wiesz, gdzie szukać.

+1

Jest to problem spowodowany w szczególności przez leniwych I/O, a nie przez leniwe oceny w ogóle. Lazy I/O jest w rzeczywistości dość niebezpieczne i sprzeczne z duchem programowania funkcjonalnego, ponieważ daje efekty uboczne funkcjom, które powinny być czyste (mianowicie ocena łańcucha powoduje odczyt danych z dysku - efekt uboczny!), Prowadząc do problemy takie jak ten, a także ten: http://stackoverflow.com/questions/2981582/haskell-lazy-io-and-closing-files Ale z pewnością możesz leniwy ocenić bez leniwego I/O, w rzeczywistości, taki wydaje się być obecny kierunek Haskella. – Jesse

+0

To jest czysty przykład! – vy32

4

Nie można wykonać redukcji (np. Zagięcia) danych wejściowych w stałej przestrzeni z leniwą oceną, ponieważ opóźniona ocena każdego kroku redukcji powoduje złożoność liniowej przestrzeni. Zamiast tego należy wymusić wymuszenie oceny wyniku każdego kroku redukcji, aby utrzymać stałe wykorzystanie przestrzeni.

Na przykład hashowanie pliku w Haskell. Możesz mieć dobre intencje i czytać plik wejściowy leniwie po kawałku, dodając każdą porcję do skrótu, ale za plecami Haskell jest w rzeczywistości za każdym kawałkiem dodanym do podsumowania, pozostawiając cały plik w pamięci te uderzenia do momentu, aż wynikowy skrót zostanie faktycznie oceniony. Oooo!

Zobacz ostatni komentarz tutaj: Haskell lazy I/O and closing files