Когда ленивая оценка бесполезна? - PullRequest
5 голосов
/ 30 августа 2009

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

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

Ответы [ 7 ]

4 голосов
/ 09 июня 2010

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

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

См. Последний комментарий здесь: Ленивый ввод-вывод на Haskell и закрытие файлов

3 голосов
/ 30 августа 2009

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

2 голосов
/ 19 мая 2010

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

import System.IO

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

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

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

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

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

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

2 голосов
/ 19 мая 2010

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

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

0 голосов
/ 24 ноября 2009

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

0 голосов
/ 30 августа 2009

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

0 голосов
/ 30 августа 2009

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

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

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

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

...