延迟执行几乎总是一件好事。但是有些情况下,这是一个问题,你诉诸“获取”(在Nhibernate)急切地获取它。
你知道懒惰的评价会让你反感的实际情况......?
答案 0 :(得分:4)
由于每个缩小步骤的延迟评估会导致线性空间复杂度,因此不能对具有延迟评估的恒定空间中的输入数据进行缩减(例如,折叠)。您必须强制评估每个缩减步骤的结果,以保持空间使用不变。
例如,在Haskell中散列文件。你可能很有意义并且懒惰地读取输入文件chunk-by-chunk,将每个块添加到摘要中,但是在你的背后Haskell实际上为你添加到摘要的每个chunk做了一个thunk,将整个文件保留在内存中这些thunks直到实际评估得到的摘要。哎哟!
请参阅此处的最新评论:Haskell lazy I/O and closing files
答案 1 :(得分:3)
在性能至关重要且必须始终评估值的情况下,延迟评估无效。在这些情况下,您最好只评估值并完成它,因为懒惰评估的开销将被浪费。
答案 2 :(得分:2)
当评估可能产生副作用时,懒惰评估无用。这是唯一的原因,这就是为什么只有纯功能语言才有它。如果表达式具有必须以特定顺序发生的副作用,则无法获得它。
除此之外,懒惰评估只会提高性能,这是它的主要目标。这就是为什么有些语言禁止副作用,为了达到妥协而获得懒惰的评价,另一个很好的效果就是控制结构可以是常规函数。
答案 3 :(得分:2)
懒惰造成奇怪问题的一个例子(今天发生在我身上,在Haskell中):
import System.IO
main = do
content <- readFile "foo.txt"
writeFile "foo.txt" content
编译时会抛出以下错误&amp;执行:
foo.txt: openFile: resource busy (file is locked)
我认为它会做什么: 打开文件foo.txt,阅读内容,再次关闭它。然后打开它进行写入,编写内容,然后再将其关闭。
它实际上做了什么: “啊,有些内容。我可能会在以后需要的时候阅读它。”然后打开“foo.txt”进行写作。开始写内容......好吧,现在我们需要内容。打开foo.txt阅读 - bam!
我知道解决这个问题很简单,但如果你不知道在哪里找,很难找到。
答案 4 :(得分:0)
延迟加载资源涉及在每个加载的请求者和源之间来回跳转。在NHibernate的情况下,这意味着从应用程序到数据库(通常在不同的服务器上)。
每次旅行经常会产生开销(当然有NHibernate或任何其他数据库查询)。
如果您知道自己需要全部或大部分数据,最好一次性完成,只需支付一次开销。
一个典型的例子是当你需要拉回一个对象列表来填充一个组合框(通常这些将是配置对象)。每次将列表成员添加到组合框时,延迟加载都将返回到数据库。由于您将整个列表放入组合框中,因此延迟获取每个对象会产生大量额外开销。
答案 5 :(得分:0)
这也可能是您的程序的用户体验的问题。在app加载期间,当屏幕上显示横幅时,人们会愉快地等待5秒钟,但是当他们在文本框中输入内容时,他们鄙视必须等待0.25秒。如果热切地加载所有数据所花费的时间并不长,您可以考虑在人们接受延迟的工作流程中的某个时刻(例如应用加载,弹出窗口,按下按钮)。
答案 6 :(得分:0)
当您不想存储值时,延迟评估没有用,只需使用它即可。但这取决于惰性求值程序的实现。某些系统(如Haskell)可以判断是否会再次使用某个值。其他一些人不能也可能导致泄密。