At a skim, seems like a reasonable thing to do.
On Wednesday, December 11, 2019 at 5:04:38 AM UTC-6, Dirk Wetzel wrote:
>
> Hey everyone! :)
>
> I was recently looking at the source for *get-in* to check if it would
> exit early as soon as a key was not present in the nested maps.
> The source for quick reference:
>
> (defn get-in
> "Returns the value in a nested associative structure,
> where ks is a sequence of keys. Returns nil if the key
> is not present, or the not-found value if supplied."
> {:added "1.2"
>:static true}
> ([m ks]
> (reduce1 get m ks))
> ([m ks not-found]
> (loop [sentinel (Object.)
> m m
> ks (seq ks)]
>(if ks
> (let [m (get m (first ks) sentinel)]
>(if (identical? sentinel m)
> not-found
> (recur sentinel m (next ks
> m
>
> I noticed that the 2-arity variant does not exit early, but the 3-arity
> variant does. Also looking at the implementation of *reduce1* vs the
> implementation of the 3-arity variant of *get-in* got me thinking if it
> wouldn't be slightly more efficient to just implement the 2-arity variant
> by calling the 3-arity variant, eg:
>
> ([m ks]
>(get-in m ks nil))
>
> I've run a few micro benchmarks comparing speeds of the 2-arity and
> 3-arity variant using *criterium* and the 3-arity variant seems to be
> more efficient even if it can't exit early.
> Below are a few of the criterium benchmarks I did on my laptop:
>
> (crit/bench (get-in {} [:a :b]))
>
> Evaluation count : 1874799960 in 60 samples of 3124 calls.
> Execution time mean : 32.013948 ns
> Execution time std-deviation : 1.172814 ns
>Execution time lower quantile : 29.839525 ns ( 2.5%)
>Execution time upper quantile : 34.283877 ns (97.5%)
>Overhead used : 2.189987 ns
>
> Found 17 outliers in 60 samples (28. %)
> low-severe 13 (21.6667 %)
> low-mild 4 (6.6667 %)
> Variance from outliers : 23.7873 % Variance is moderately inflated by
> outliers
>
> (crit/bench (get-in {} [:a :b] nil))
>
> Evaluation count : 4071018060 in 60 samples of 67850301 calls.
> Execution time mean : 15.124086 ns
> Execution time std-deviation : 1.492542 ns
>Execution time lower quantile : 12.488672 ns ( 2.5%)
>Execution time upper quantile : 17.908223 ns (97.5%)
>Overhead used : 2.189987 ns
>
> Found 1 outliers in 60 samples (1.6667 %)
> low-severe 1 (1.6667 %)
> Variance from outliers : 68.6898 % Variance is severely inflated by
> outliers
>
> (crit/bench (get-in {:a {:b {:c 1}}} [:a :b :c]))
>
> Evaluation count : 1034704440 in 60 samples of 17245074 calls.
> Execution time mean : 58.600293 ns
> Execution time std-deviation : 2.939752 ns
>Execution time lower quantile : 55.782160 ns ( 2.5%)
>Execution time upper quantile : 64.772887 ns (97.5%)
>Overhead used : 2.189987 ns
>
> Found 2 outliers in 60 samples (3. %)
> low-severe 2 (3. %)
> Variance from outliers : 36.8128 % Variance is moderately inflated by
> outliers
>
> (crit/bench (get-in {:a {:b {:c 1}}} [:a :b :c] nil))
>
> Evaluation count : 1359247260 in 60 samples of 22654121 calls.
> Execution time mean : 42.744780 ns
> Execution time std-deviation : 3.356838 ns
>Execution time lower quantile : 39.571655 ns ( 2.5%)
>Execution time upper quantile : 48.841751 ns (97.5%)
>Overhead used : 2.189987 ns
>
> Found 1 outliers in 60 samples (1.6667 %)
> low-severe 1 (1.6667 %)
> Variance from outliers : 58.4799 % Variance is severely inflated by
> outliers
>
>
> While I can imagine that changing the implementation of the 2-arity
> variant would barely bring noticeable improvements to projects, I also
> can't see much of a reason not to change it. It doesn't make the code less
> readable or maintainable. It just makes performance for both arities
> consistently good.
>
> What would be pros and cons of such a change that I don't see at the
> moment?
>
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to clojure+unsubscr...@googlegroups.com.
To view this discussion on the web visit
https://groups.google.com/d/msgid/clojure/e40639e3-20da-4700-a590-e59662877a55%40googlegroups.com.