简体   繁体   English

具有两个元素的assoc-in和update / assoc之间的区别

[英]Differences between assoc-in with two elements and update / assoc

I've been doing for a while things like (assoc-in my-hash [:data :id] 1) , and it looks fine. 我已经做了一段时间了,例如(assoc-in my-hash [:data :id] 1) ,看起来还不错。

Recently, since I rarely have more than two levels, I noticed I can do (update my-hash :data assoc :id 1) , which sounds totally different, but returns the same. 最近,由于我很少拥有两个以上的级别,因此我注意到我可以做(update my-hash :data assoc :id 1) ,听起来完全不同,但返回的结果相同。

So, I wonder, is there any difference in performance? 因此,我想知道性能是否有差异? Do you think it's more readable in one way than the other? 您是否认为一种方式比另一种方式更具可读性? More idiomatic? 更惯用吗?

update / assoc feels like it's more expensive to me, but I really like it better than assoc-in , which makes me stop to think each time I see it. update / assoc感觉对我来说更昂贵,但是我真的比assoc-in更喜欢它,这使我每次看到它都停下来思考。

When it comes to performance, it's always good to measure. 当涉及到性能时,总是很容易衡量。 Ideally you'd assemble a realistic map (whether your maps are big or small will have some impact on the relative cost of various operations) and try it both ways with Criterium : 理想情况下,您将组装一张真实的地图(无论您的地图大小,都会对各种操作的相对成本产生一定的影响),并使用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)))

Under the hood, update + assoc is sort of the unrolled version of assoc-in here that doesn't need the auxiliary vector to hold the keys, so I would expect it to be faster than assoc-in . 在幕后, update + assoc有点像assoc-in的展开版本, assoc-in这里不需要辅助向量来保存键,因此我希望它比assoc-in更快。 But (1) ordinarily I wouldn't worry about minor performance differences when it comes to things like this, (2) when I do care, again, it's better to measure than to guess. 但是(1)通常情况下,我不会担心性能方面的细微差别,(2)当我确实关心的时候,再次衡量要比猜测好。

(On my box, with Clojure 1.9.0-alpha14, update + assoc is indeed faster at ~282 ns vs ~353 ns for assoc-in given my small test map of (assoc (into {} (map #(vector % %)) (range 20)) :data {:id 0}) .) (在我的框,使用Clojure 1.9.0-alpha14, update + assoc是在〜282纳秒VS为〜353纳秒确实更快assoc-in给出我小的测试图的(assoc (into {} (map #(vector % %)) (range 20)) :data {:id 0}) 。)

Ultimately most of the time readability will be the more important factor, but I don't think you can say in general than one approach is more readable than the other. 最终,在大多数情况下,可读性将是更重要的因素,但我认为您通常不能说一种方法比另一种方法更具可读性。 If you have a chain that already uses assoc-in or update multiple times, it may be preferable to repeat the same function for the sake of consistency (just to avoid making the reader wonder "is this thing really different"). 如果您的链已经使用assoc-in或多次update ,则出于一致性考虑,最好重复使用相同的功能(只是避免使读者怀疑“这东西真的不同”)。 If you have a codebase that you control, you can adopt a "house style" that favours one approach over the other. 如果您拥有自己控制的代码库,则可以采用一种“家庭风格”,这种家庭风格偏爱一种方法。 Etc., etc. 等等

I might see assoc-in as a little more readable most of the time – it uses a single "verb" and makes it clear at a glance what the (single, exact) path to the update is – but if you prefer update + assoc and expect to keep their use consistent in your codebase, that's certainly fine as well. assoc-in大多数情况下,我可能会看到assoc-in更具可读性-它使用一个“动词”并一目了然地知道更新的(唯一,准确)路径是什么-但如果您喜欢update + assoc并希望它们在代码库中的使用保持一致,这当然也很好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM