简体   繁体   中英

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.

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.

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.

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 :

(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 . 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.

(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}) .)

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"). 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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