Clojure 具有两个元素的assoc与update/assoc之间的差异

Clojure 具有两个元素的assoc与update/assoc之间的差异,clojure,functional-programming,hashmap,Clojure,Functional Programming,Hashmap,我已经做了一段时间了,比如(我的hash[:data:id]1中的assoc),看起来不错 最近,由于我很少有两个以上的级别,我注意到我可以执行(更新我的hash:data assoc:id 1),这听起来完全不同,但返回的是相同的 所以,我想知道,在表现上有什么不同吗?你认为它在某种程度上比另一种更具可读性吗?更地道 update/assoc对我来说似乎更贵,但我真的喜欢它胜过assoc in,这让我每次看到它都会停下来思考。说到性能,衡量总是好的。理想情况下,您可以组装一张真实的地图(无论地

我已经做了一段时间了,比如
(我的hash[:data:id]1中的assoc)
,看起来不错

最近,由于我很少有两个以上的级别,我注意到我可以执行
(更新我的hash:data assoc:id 1)
,这听起来完全不同,但返回的是相同的

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


update/assoc
对我来说似乎更贵,但我真的喜欢它胜过
assoc in
,这让我每次看到它都会停下来思考。

说到性能,衡量总是好的。理想情况下,您可以组装一张真实的地图(无论地图大小,都会对各种操作的相对成本产生一定影响),并尝试以下两种方法:

在引擎盖下,
update
+
assoc
assoc在这里的展开版本,它不需要辅助向量来固定键,因此我希望它比
中的assoc快。但是(1)一般来说,当涉及到这样的事情时,我不会担心细微的性能差异,(2)当我真的关心时,再次强调,测量比猜测更好

(在我的盒子里,使用Clojure 1.9.0-alpha14,
更新
+
assoc
确实比
assoc在
中的353ns更快,因为我的
测试图很小(assoc(进入{}(映射#(向量%)(范围20)):data{:id 0}

最终,在大多数情况下,可读性将是更重要的因素,但我认为一般来说,你不能说一种方法比另一种方法更具可读性。如果您有
链已经多次使用了
assoc
update
,为了保持一致性,最好重复相同的功能(只是为了避免让读者怀疑“这东西真的不同吗”)。如果您有一个您可以控制的代码库,那么您可以采用一种方法优于另一种方法的“内部风格”。等等等等


我可能认为
中的
assoc在大多数情况下更具可读性–它使用一个“动词”,一眼就能清楚地知道更新的(单一、准确)路径是什么–但是如果您更喜欢
update
+
assoc
,并希望在您的代码库中保持它们的使用一致,这当然也很好。

中的assoc在我看来更具可读性。您可以看到您正在将一个值关联到一个映射中,它的路径是
:data
,然后是
:id
——简单易读。同时,考虑< <代码> >中的函数<代码> ASSOC是为了这个目的而设计的;将函数用于其预期目的意味着代码通常更清晰,而且核心库的公共词汇表对阅读它的任何人都是清晰的。除非每秒执行次数超过100000次(在这种情况下,无论如何你都会使用瞬变),否则我根本不会担心速度会变慢。确切地说,看起来每个人都在
中使用
assoc,但是
更新
是一种新功能(我认为是在1.8.0中添加的),因此它可能会打开一种新的执行方式,但是是的,我将保持
assoc in
:与
assoc in
相比,
update(-in)/assoc
的另一个小区别(优点)是,您可以同时关联多个k/v-s。@cfrick确实!JIRA中有一张票证,支持在
中的
中关联多个键/值对。它是在很久以前发布的,从那时起就一直处于休眠状态,但现在似乎有一些人对此感兴趣(Alex Miller最近对它进行了预选)。是的,我认为这场演出其实没什么大不了的,只是想看看其他人对此的看法。我同意
assoc in
可能是“正常”的方式,也许我只是坚持
assoc in
并习惯它。谢谢!:)
(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)))