Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (defn compile-get-in [path]
- (let [f (reduce
- (fn [acc k]
- (fn [m] (get (acc m) k)))
- identity path)]
- (fn [m]
- (f m))))
- (let [m {:a {:b 1}}]
- (time (dotimes [i 100000]
- (get-in m [:a :b]))))
- ;; => "Elapsed time: 11.897221 msecs"
- (let [m {:a {:b 1}}
- compiled-get-in-fn (compile-get-in [:a :b])]
- (time (dotimes [i 100000]
- (compiled-get-in-fn m))))
- ;; => "Elapsed time: 5.3357 msecs"
- ;; Significantly more efficient for larger paths and matching maps
- (let [m {:a {:b {:c {:d 1}}}},
- compiled-get-in-fn (compile-get-in [:a :b :c :d])]
- (time (dotimes [i 100000]
- (compiled-get-in-fn m))))
- ;; => "Elapsed time: 8.376878 msecs"
- (let [m {:a {:b {:c {:d 1}}}}]
- (time (dotimes [i 100000]
- (get-in m [:a :b :c :d]))))
- ;; => "Elapsed time: 14.608494 msecs"
- ;; Benefit seems to get smaller with an increasing path size and no match
- ;; One option would be to terminate the loop premature when sentinel value has been found
- (let [m {:a {:b 1}}]
- (time (dotimes [i 100000]
- (get-in m [:a :b :c :d]))))
- ;; => "Elapsed time: 22.612878 msecs"
- (let [m {:a {:b 1}},
- compiled-get-in-fn (compile-get-in [:a :b :c :d])]
- (time (dotimes [i 100000]
- (compiled-get-in-fn m))))
- ;; => "Elapsed time: 18.415237 msecs"
- ;; Adjusted version for no matching paths?
- (defn compile-get-in [path]
- (let [f (reduce
- (fn [acc k]
- (fn [m] (when-let [m0 (acc m)]
- (get m0 k))))
- identity path)]
- (fn [m]
- (f m))))
- (let [m {:a {:b 1}},
- compiled-get-in-fn (compile-get-in [:a :b :c :d])]
- (time (dotimes [i 100000]
- (compiled-get-in-fn m))))
- ;; => "Elapsed time: 12.751598 msecs"
- ;; Matched version is faster?
- (let [m {:a {:b {:c {:d 1}}}},
- compiled-get-in-fn (compile-get-in [:a :b :c :d])]
- (time (dotimes [i 100000]
- (compiled-get-in-fn m))))
- ;; => "Elapsed time: 7.738589 msecs"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement