haskell - 函数式编程语言中的自动内存

标签 haskell functional-programming memoization

我一直认为 Haskell 会做某种自动智能内存。例如,朴素的斐波那契实现

fib 0 = 0
fib 1 = 1
fib n = fib (n-2) + fib (n-1)

因此会很快。现在我读this看来我错了——Haskell 似乎没有自动内存功能。还是我理解有问题?

是否有其他语言可以自动(即隐式,非显式)内存?

实现记忆化的常见方法有哪些?在我见过的所有示例实现中,它们都使用 HashMap ,但其大小没有任何限制。显然,这在实践中行不通,因为你需要某种限制。鉴于此,它变得更加复杂,因为当你达到限制时,你必须丢弃一些数据。这就变得复杂了:限制是否应该是动态的,并且经常使用的函数应该比不经常使用的函数有更高的限制?当你达到极限时,你会扔掉哪些条目?就只是最新用过的吗?在这种情况下,您还需要对数据进行排序。您可以使用链表和 HashMap 的某种组合来实现这一点。这是常见的方式吗?

您能否链接(或引用)一些常见的现实世界实现?

谢谢, 阿尔伯特

<小时/>

编辑:我最感兴趣的是我描述的问题,即如何实现这样的限制。任何对解决这个问题的论文的引用都会非常好。

<小时/>

编辑:可以找到一些自己对示例实现(有限制)的想法here .

<小时/>

编辑:我并不是想解决特定应用程序中的特定问题。我正在寻找通用的内存解决方案,该解决方案可以全局应用于(纯函数)程序的所有函数(因此不实现内存限制的算法不是解决方案)。当然,(可能)没有最佳/最佳解决方案。但这让我的问题同样有趣。

为了尝试这样的解决方案,我考虑将其添加到 Haskell 作为优化。我真的很想知道它的性能如何。

我想知道是否有人已经这样做了。

最佳答案

我在评论中说过,您的要求听起来像是垃圾收集。我这样想是因为您有兴趣管理有限的内存池,偶尔清除它,这样它就不会溢出。

现在想想,它更像是虚拟内存page replacement algorithm 。您可以阅读该维基百科页面,了解用于解决此类问题的各种方法,例如“最近未使用”、“老化”、“时钟”、“第二次机会”等。

但是,内存通常不是通过限制保留的结果来完成的;上述算法所需的变异通常是非 haskell 式的。不过,不要因此而泄气。您有一些有趣的想法,这些想法可能会对迄今为止在 Haskell 中进行的内存可能性探索产生有值(value)的补充。

有时,特定的内存问题很适合有限的内存。例如,可以通过动态编程(参见维基百科的Dynamic Programming # Sequence alignment)和二维内存表来对齐两个基因序列。但由于给定单元格的 DP 解仅取决于前一行的结果,因此您可以从底部开始并丢弃距当前行超过 1 的行。斐波那契数是相同的:您只需要序列中的前两个数字即可计算下一个数字。如果您只感兴趣n个数字,您可以提前放弃任何内容。

大多数内存都是为了加速存在共享子问题的递归算法。许多此类问题没有一种简单的方法来对评估进行排序,以便丢弃不再需要的结果。此时,您只是猜测,使用启发式方法(例如使用频率)来确定谁可以获得对有限资源的多少访问权限。

关于haskell - 函数式编程语言中的自动内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5749039/

相关文章:

python可重置实例方法内存装饰器

python - 可以做些什么来加速这个 memoization 装饰器?

haskell - 内存和重复 IO monad

haskell - haskell中模式解析错误

haskell - 这个函数会产生什么

haskell - Haskell 中的树构建函数(作业)

javascript - 如何提高JS函数式代码的性能

functional-programming - Java 8函数样式以索引进行迭代

haskell - 类型推导在 Haskell 中是如何工作的?

Javascript 在不关心结果时迭代列表中的两个元素?