与两个元素的关联和update/assoc之间的差异

gri*_*lix 1 functional-programming clojure hashmap

我已经做了一段时间的事情(assoc-in my-hash [:data :id] 1),看起来很好.

最近,由于我很少有超过两个级别,我注意到我可以做(update my-hash :data assoc :id 1),听起来完全不同,但返回相同.

所以,我想知道,性能有什么不同吗?你认为它在某种程度上比另一种更具可读性吗?更惯用吗?

update / assoc感觉它对我来说更贵,但我真的更喜欢它assoc-in,这让我每次看到它都会停下来思考.

Mic*_*zyk 5

在性能方面,衡量总是好的.理想情况下,您将组装一个真实的地图(无论您的地图是大还是小都会对各种操作的相对成本产生一些影响),并使用Criterium尝试两种方式:

(require '[criterium.core :as c])

(let [m (construct-your-map)]
  (c/bench (assoc-in m [:data :id] 1))
  (c/bench (update m :data assoc :id 1)))
Run Code Online (Sandbox Code Playgroud)

在引擎盖下,update+ assocassoc-in这里的展开版本,不需要辅助向量来保存键,所以我希望它比它更快assoc-in.但是(1)通常我不担心在这样的事情上会出现轻微的性能差异,(2)当我关心时,再次,测量比猜测更好.

(在我的盒子上,使用Clojure 1.9.0-alpha14,对于给定我的小测试图,update+ assoc在~282 ns和~353 ns之间确实更快.)assoc-in(assoc (into {} (map #(vector % %)) (range 20)) :data {:id 0})

最终,大部分时间的可读性将是更重要的因素,但我认为你不能说一般方法比另一种方法更具可读性.如果你有一个?已经使用链assoc-inupdate多次,它可能是最好重复相同功能的一致性的缘故(只是为了避免使读者奇迹"是这玩意儿真不同").如果您拥有一个可以控制的代码库,那么您可以采用一种"家居风格",这种风格有利于一种方法而不是另一种方式.等等

我可能会assoc-in在大多数情况下看到更具可读性 - 它使用单个"动词"并且一目了然地说明更新的(单个,精确)路径是什么 - 但是如果你更喜欢update+ assoc并希望保留他们的在代码库中使用一致,这当然也很好.

  • `update(-in)/ assoc`与`assoc-in`的另一个微小区别(优点)是,你可以同时关联多个k/vs. (3认同)