I’m writing a simple function: given a number, it will return a sequence or a collection of the digits in the number (in the correct order). i.e `(get-digits-fn 1234567) => (1 2 3 4 5 6 7) / [1 2 3 4 5 6 7]`

Below are five attempts at the same function:

`(defn get-digits-1 [num] (->> [num '()] (iterate (fn [[num digits]] (when (> num 0) [(quot num 10) (conj digits (rem num 10))]))) (take-while some?) (last) (second))) (defn get-digits-2 [num] (when (> num 0) (lazy-seq (concat (get-digits-2 (quot num 10)) '((rem num 10)))))) ;; Suggested by Carcigenate (defn get-digits-3 [num] (->> (str) (map str) (map int) (into '()))) (defn get-digits-4 [num] (loop [n num res '()] (if (= n 0) res (recur (quot n 10) (conj res (rem n 10)))))) (defn get-digits-5 [num] (->> (iterate (fn [[n digits]] [(quot n 10) (conj digits (rem n 10))]) [num '()]) (drop-while #(not= 0 (first %))) (first) (second))) `

A helper function for testing performance:

`(defn quick-bench-get-digits [fn range] (quick-bench (->> range (map fn) (map (partial apply vector)) (into [])))) `

The perf results (output truncated to only show execution time mean):

`eul> (quick-bench-get-digits get-digits-1 (range 1 100000)) Execution time mean : 129.516521 ms eul> (quick-bench-get-digits get-digits-2 (range 1 100000)) Execution time mean : 128.637055 ms eul> (quick-bench-get-digits get-digits-3 (range 1 100000)) Execution time mean : 24.267716 ms eul> (quick-bench-get-digits get-digits-4 (range 1 100000)) Execution time mean : 25.083393 ms eul> (quick-bench-get-digits get-digits-5 (range 1 100000)) Execution time mean : 145.430443 ms `

It looks like `get-digits-3`

is the fastest while `get-digits-4`

is closely behind. (As the numbers increase, `get-digits-3`

outperforms `get-digits-4`

. i.e try `(range 1000000 2000000)`

)

- Any way to increase performance more without leaving Clojure land?
- If mutability and Java inter-op is allowed, is there a way to increase performance?

p.s. functions 1 and 5 are almost identical. This was incremental exploration.