2009-08-30 2 views
5

Задержка исполнения почти всегда является благом. Но тогда бывают случаи, когда это проблема, и вы прибегаете к «fetch» ​​(в Nhibernate), чтобы получить ее.Когда ленивая оценка не полезна?

Знаете ли вы практические ситуации, когда ленивая оценка может укусить вас ...?

ответ

0

Ленивые загрузочные ресурсы включают в себя поездку туда и обратно между запрашивающим и источником для каждой нагрузки. В случае NHibernate это означает, что из приложения в базу данных (которая часто находится на другом сервере).

С каждой поездкой (например, для NHibernate или любого другого запроса БД) часто возникают накладные расходы.

Если вы знаете, что вам понадобятся все или значительная часть данных, вам лучше потянуть его за один раз и только один раз нанести накладные расходы.

Классический пример - когда вам нужно отбросить список объектов, чтобы заполнить поле со списком (часто это будут объекты конфигурации). Lazy loading будет возвращаться в базу данных каждый раз, когда вы добавите член списка в поле со списком. Так как вы вставляете весь список в поле со списком, вы будете обладать множеством дополнительных накладных расходов, чтобы ленить выборку каждого объекта.

0

Это может быть проблема с пользовательской практикой вашей программы. Люди будут счастливо ждать 5 секунд, когда баннер будет отображаться на экране во время загрузки приложения, но они не хотят ждать 0,25 секунды, когда они печатают что-то в текстовом поле. Если время, затраченное на загрузку всех ваших данных, не так долго, вы можете подумать об этом в какой-то момент рабочего процесса, когда люди принимают задержку (например, загрузка приложения, всплывающее окно, нажатия кнопок).

3

Ленивая оценка не полезна в ситуациях, когда производительность критическая, а значение должно быть всегда. В этих случаях вам лучше просто оценить ценность и сделать с ней, потому что накладные расходы ленивой оценки будут потрачены впустую.

+0

оценка Ленивый является способом, чтобы получить работу. – Zorf

+5

Неверный. Если вы должны оценить ответ, то дополнительные накладные расходы для ленивой оценки создают стоимость без каких-либо преимуществ. – vy32

+0

vy32 верен. Например, если у вас есть список объектов, которые отображаются в списке на мобильном устройстве, представление будет создано в тот момент, когда элементы списка появятся на экране. Если некоторые значения, отображаемые в списке, должны быть ленивы загружены, список заикается и отстает, потому что новые списки не могут быть заполнены достаточно быстро. – Janusz

0

ленивая оценка не полезна, когда вы не хотите хранить ценность, просто используйте ее. Но это зависит от реализации ленивого оценщика. Некоторые системы (например, Haskell) могут определить, будет ли значение использоваться снова. Некоторые другие не могут и могут вызывать утечки.

2

Ленивая оценка не полезна, когда оценка может иметь побочные эффекты. Это единственная причина, и именно поэтому ее используют только чисто функциональные языки. Если выражения могут иметь побочные эффекты, которые должны произойти в определенном порядке, вы не можете его получить.

Кроме того, ленивая оценка только повышает производительность, вот и главная цель. И поэтому некоторые языки запрещают побочные эффекты, получают ленивую оценку за этот компромисс, еще один приятный эффект от этого - структуры управления могут быть регулярными функциями.

2

Одним из примеров ленивости вызывает странные проблемы (случилось со мной сегодня, в Haskell):

import System.IO 

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

Это выдает следующее сообщение об ошибке при компиляции & выполняется:

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

То, что я думал, что это будет do: Открыть файл foo.txt, прочитать содержимое, снова закрыть его. Затем откройте его для записи, напишите содержимое и закройте его снова.

Что он на самом деле сделал: «Ах, какое-то содержание. Я, вероятно, прочитаю его позже, когда мы действительно это понадобимся». Затем откройте «foo.txt» для записи. Начните писать контент ... нормально, теперь нам нужен контент. Откройте foo.txt для чтения - bam!

Я знаю, что это тривиально исправлять, но трудно найти, не знаете, где искать.

+1

Это проблема, вызванная, в частности, ленивым вводом-выводом, а не ленивой оценкой в ​​целом. Lazy I/O на самом деле довольно опасен и против духа функционального программирования, поскольку он дает побочные эффекты для функций, которые должны быть чистыми (а именно, оценка строки заставляет данные считываться с диска - побочный эффект!), Что приводит к проблемы, подобные этому, и этот тоже: http://stackoverflow.com/questions/2981582/haskell-lazy-io-and-closing-files. Но вы, безусловно, можете иметь ленивую оценку без ленивых операций ввода-вывода, похоже, это настоящее направление Хаскелла. – Jesse

+0

Это пример! – vy32

4

Вы не можете сделать сокращение (например, сгиб) на входных данных в постоянном пространстве с ленивой оценкой, так как отложенная оценка каждого этапа восстановления приводит к сложности линейного пространства. Вместо этого вы должны принудительно оценить результат каждого шага сокращения, чтобы сохранить использование пространства постоянным.

Например, хэширование файла в Haskell. Возможно, вы хорошо понимаете и читаете входной файл lazily chunk-by-chunk, добавляя каждый фрагмент в дайджест, но за вашей спиной Haskell на самом деле делает thunk для каждого фрагмента, который вы добавляете в дайджест, оставляя весь файл в памяти в эти трюки до тех пор, пока итоговый дайджест не будет фактически оценен. Ой!

Посмотреть последний комментарий здесь: Haskell lazy I/O and closing files