【问题标题】:Memoize over one parameter记住一个参数
【发布时间】:2018-08-02 07:18:26
【问题描述】:

我有一个函数,它需要两个我想记住的输入。函数的输出仅取决于第一个输入的值,第二个输入的值对结果没有函数影响(但可能会影响完成所需的时间)。因为我不希望第二个参数影响记忆,所以我不能使用memoize。有没有一种惯用的方法来做到这一点,还是我只需要自己实现记忆?

【问题讨论】:

  • 你能分享一个你的函数的例子(甚至是人为的)吗?
  • 如果是这种情况,您基本上是在说“额外”参数不会影响结果——那么为什么您的函数需要它呢?您可以创建一个只接受 重要 的参数的函数,记住它,然后从一个也接受 不重要 的 arg 的函数调用它。跨度>
  • 这可能完全是左字段,因为我刚醒来,但是鉴于您的最后评论,懒惰地进行搜索,返回懒惰的结果,然后再考虑起始位置可能是有意义的在不同的功能。如果第二个参数只有改变执行时间的效果,那么看起来它实际上与函数的操作没有任何关系,这表明该函数做的太多了。
  • @Carcigenicate 我有同样的想法,将有助于查看实际代码
  • @OParry 我会把它扔在那里:如果你使用这里建议的记忆技术组合一个完整的工作解决方案并将其发布到代码审查,我会(和其他人一起在这里我当然)有兴趣对其进行审查以提出不同的方式。你在这里有你的记忆答案,但正如我上面提到的,我怀疑有更好的方法来解决这个问题。

标签: clojure memoization


【解决方案1】:

我建议为此使用缓存(如 clojure.core.cache)而不是函数记忆:

(defonce result-cache
  (atom (cache/fifo-cache-factory {})))

(defn expensive-fun [n s]
  (println "Sleeping" s)
  (Thread/sleep s)
  (* n n))

(defn cached-fun [n s]
  (cache/lookup
    (swap! result-cache
           #(cache/through
              (fn [k] (expensive-fun k s))
              %
              n))
    n))

(cached-fun 111 500)
Sleeping 500
=> 12321
(cached-fun 111 600) ;; returns immediately regardless of 2nd arg
=> 12321
(cached-fun 123 600)
Sleeping 600
=> 15129

【讨论】:

    【解决方案2】:

    memoize 不支持仅在某些 args 上进行缓存,但很容易自己制作:

    (defn search* [a b]
      (* a b))
    
    (def search
      (let [mem (atom {})]
        (fn [a b]
          (or (when-let [cached (get @mem a)]
                (println "retrieved from cache")
                cached)
              (let [ret (search* a b)]
                (println "storing in cache")
                (swap! mem assoc a ret)
                ret)))))
    

    【讨论】:

    • 我认为如果你所有的缓存结果都适合内存,不需要驱逐策略等,这种简单的方法更可取。
    【解决方案3】:

    您可以将您的函数包装到另一个函数(带有一个参数)中,并使用第二个默认参数调用它。然后你就可以记忆新功能了。

    (defn foo
      [param1]
      (baz param1 default-value))
    

    【讨论】:

    • 问题是,这不是意味着每次我想更改第二个参数的值时,我都会丢失所有以前的记忆数据吗?
    猜你喜欢
    • 2016-08-26
    • 2011-04-04
    • 2011-08-18
    • 2013-12-31
    • 1970-01-01
    • 2012-12-14
    • 2016-06-01
    • 2012-10-07
    • 1970-01-01
    相关资源
    最近更新 更多