Clojure 记忆一个参数
我有一个函数,它接受两个我想记忆的输入。函数的输出仅取决于第一个输入的值,第二个输入的值对结果没有函数影响(但可能会影响完成所需的时间)。由于我不希望第二个参数影响记忆,因此无法使用Clojure 记忆一个参数,clojure,memoization,Clojure,Memoization,我有一个函数,它接受两个我想记忆的输入。函数的输出仅取决于第一个输入的值,第二个输入的值对结果没有函数影响(但可能会影响完成所需的时间)。由于我不希望第二个参数影响记忆,因此无法使用memoize。是否有一种惯用的方法来实现这一点,或者我只需要自己实现记忆功能?您可以将您的函数包装到另一个函数中(使用一个参数),并将其称为具有第二个默认参数的函数。然后您可以记忆新函数 (defn foo [param1] (baz param1 default-value)) 您可以将函数包装成另一个
memoize
。是否有一种惯用的方法来实现这一点,或者我只需要自己实现记忆功能?您可以将您的函数包装到另一个函数中(使用一个参数),并将其称为具有第二个默认参数的函数。然后您可以记忆新函数
(defn foo
[param1]
(baz param1 default-value))
您可以将函数包装成另一个函数(使用一个参数),并使用第二个默认参数将其称为函数。然后您可以记忆新函数
(defn foo
[param1]
(baz param1 default-value))
我建议对此使用缓存(如)而不是函数记忆:
(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
我建议对此使用缓存(如)而不是函数记忆:
(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
memoize
不支持仅在某些参数上进行缓存,但很容易自己进行缓存:
(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)))))
memoize
不支持仅在某些参数上进行缓存,但很容易自己进行缓存:
(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)))))
你能分享你函数的一个例子吗(甚至是人为的)?如果是这样,你基本上是说“额外”参数不会影响结果,那么为什么你的函数需要它呢?你可以创建一个只接受重要参数的函数,将其记忆,然后从一个也接受无关紧要参数的函数调用它。这可能是我刚醒来时完全留下的字段,但鉴于你最后的评论,懒洋洋地进行搜索、返回懒洋洋的结果可能是有意义的,然后在以后的不同功能中考虑起始位置。如果第二个参数只起到改变执行时间的作用,那么它似乎实际上与函数的操作无关,这表明函数做得太多了。@Carcigenicate我也有同样的想法,这将有助于了解实际情况code@OParry我只是想说一下:如果您使用这里建议的一种记忆技术来组合一个工作完整的解决方案,并将其发布到CodeReview中,我(和这里的其他人一样)肯定会有兴趣对它进行一次回顾,以提出一种不同的方法。这里有你的记忆答案,但正如我上面提到的,我怀疑有更好的方法。你能分享一个函数的例子(甚至是人为的)吗?如果是这样,你基本上是说“额外”参数不会影响结果,那么为什么你的函数需要它?你可以创建一个只接受重要参数的函数,将其记忆,然后从一个也接受无关紧要参数的函数调用它。这可能是我刚醒来时完全留下的字段,但鉴于你最后的评论,懒洋洋地进行搜索、返回懒洋洋的结果可能是有意义的,然后在以后的不同功能中考虑起始位置。如果第二个参数只起到改变执行时间的作用,那么它似乎实际上与函数的操作无关,这表明函数做得太多了。@Carcigenicate我也有同样的想法,这将有助于了解实际情况code@OParry我只是想说一下:如果您使用这里建议的一种记忆技术来组合一个工作完整的解决方案,并将其发布到CodeReview中,我(和这里的其他人一样)肯定会有兴趣对它进行一次回顾,以提出一种不同的方法。你这里有你的回忆录答案,但正如我上面提到的,我怀疑有更好的方法来解决这个问题。问题是,这不意味着每次我想改变第二个参数的值时,我都会丢失所有以前的回忆录数据吗?问题是,这难道不意味着每次我想更改第二个参数的值时,我都会丢失所有以前的记忆数据吗?我认为如果所有缓存的结果都适合内存,不需要逐出策略,那么这种简单的方法更可取,我认为这种简单的方法更可取,如果你所有的缓存结果都能很好地放在内存中,不需要逐出策略等等。