Skip to main content
edited tags; edited title
Link
200_success
  • 145.7k
  • 22
  • 191
  • 481

Code Five functions to get the digits inof a number

added 84 characters in body
Source Link
nakiya
  • 225
  • 1
  • 7

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

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

Source Link
nakiya
  • 225
  • 1
  • 7

Code to get digits in a number

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

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