为什么我们有clojure memoize功能?

时间:2017-10-07 15:27:19

标签: clojure

我是clojure的新手,我刚刚学习并尝试了memorize功能。 在我看来,这个功能的存在很奇怪。

首先,带副作用的功能以!

结束

其次使用memorize非常简单

为什么不对我这样做呢?在内存使用和性能之间存在平衡,但是您可以轻松地让clojure运行时将一大块ram分配给函数结果。如果使用相同的参数调用函数多次使用缓存结果,如果内存耗尽,清除缓存并跟踪缓存命中,这样频繁调用的函数就不太可能从缓存中删除。

如果我设计了这个,我甚至会为函数设置最低性能级别,这样如果函数调用比缓存检索更快,它就不会被缓存。 (或者将其作为所有函数调用如何工作的属性。)

任何人都可以解释为什么clojure不会这样做

由于

1 个答案:

答案 0 :(得分:4)

计算机科学中有一个古老的笑话,只有两个难题:

  1. 缓存失效
  2. 命名事物
  3. 内置的memoize功能在它的功能方面是一个很好的开始,在少数情况下它很有用且充足。然而,它恰好符合上述笑话。这是一个有点尴尬的名字(这里的意见),它在缓存失效时失败得很厉害。它假定如果一个函数被调用过,结果总是相关的,并且函数是纯的,并且没有遇到错误,并且所有调用都是一直相关的。现实世界充满了细微差别,这对于缓存来说非常重要:

    1. 许多返回值永远无用
    2. 许多功能在范围内无限制(例如数学)
    3. 许多功能比缓存更快(再次数学)
    4. 函数具有等效参数。这些应该属于同一类。
    5. memoize实际上并不保证只运行一次函数。
    6. 许多功能永远不会是纯粹的(比如接受网络连接)
    7. 一些论点不会影响返回值。
    8. 例如,在为Web应用程序设计缓存时,所有这些都会发挥作用。 #5是一个有趣的案例,考虑一下如果你memoize一个非常慢的函数会发生什么,并且相隔一秒就有两次调用它。哪个返回值成为记忆结果?在什么情况下这很重要。这些细节确实很重要,特别是如果其中一个遇到不寻常的情况。

      在过去的八年里,我专业地做了一些回忆,我似乎已经多次在生产中使用过memoize,并且一旦不可避免地通过调用clojure.core.cache中的一个函数,它总是在短时间内被替换掉。出现问题。

      如果您发现自己想要memoize ,那么您很有可能会对core.cache 感到满意。它提供了许多细微的选项,以适应更多现实世界的案例。