1
当参数传递给一个memoised功能是一个序列memoize的一个Clojure的函数,它接受一个懒惰的顺序输入
(defn foo
([x] (println "Hello First") (reduce + x))
([x y] (println "Hello Second") (reduce + (range x y))))
(def baz (memoize foo))
传递一个ARG怎样才可以有memoize的工作:
1)
(time (baz (range 1 1000000))) ;=> Hello First "Elapsed time: 14.870628 msecs"
2)
(time (baz (range 1 1000000))) ;=> "Elapsed time: 65.386561 msecs"
传递2个ARGS:
1)
(time (baz 1 1000000)) ;=> Hello Second "Elapsed time: 18.619768 msecs"
2)
(time (baz 1 1000000)) ;=> "Elapsed time: 0.069684 msecs"
当传递2个参数的函数的第二次运行似乎是我所期望的。
但是使用矢量的工作原理。
(time (baz [1 2 3 5 3 5 7 4 6 7 4 45 6 7])) ;=> Hello First "Elapsed time: 0.294963 msecs"
(time (baz [1 2 3 5 3 5 7 4 6 7 4 45 6 7])) ;=> "Elapsed time: 0.068229 msecs"
嗯。如何处理这是一件棘手的事情 - 需要消耗整个序列来确定用于比较的身份,但能够支持ISeq的优势之一是潜在的懒惰。所以我可以看到当前语义的争论 - 我们不希望增加调用的前期成本(为了充分实现理论上可能无限的序列),以便可能启用缓存。 –
...在实现层,问题是当序列被用作映射中的键时会发生什么。即。 do序列以反映其内容(因此需要评估的O(n))的方式支持'.hashCode',以反映它们的身份(使得相同的序列仅与其自身比较)或者根本不? –
@CharlesDuffy - 序列比较(散列码等)的任何实现都只能优化不等式的情况。当'memoize'被设计为有用的时候 - 当你在地图上有相同的关键字时 - 如此矛盾地正确 - 你会以O(n)比较时间结束,不管实现是什么。故事的寓意 - “memoize”不是用于长序列作为参数。 –