DEV Community

Vee Satayamas
Vee Satayamas

Posted on

Clojure's lazy sequence versus transducer benchmark

According to this thread, I compared using only lazy sequences with transducers.

To add the I/O factor, I prepared a data file called "fake.txt" using the program below:

(with-open [w (io/writer "fake.txt")]
  (doseq [n (range 10000000)]
    (.write w (str n "\n"))))
Enter fullscreen mode Exit fullscreen mode

F1 is the lazy-sequence-based version. It reads data from "fake.txt" and does a few steps of computations.

(defn f1
  []
  (with-open [r (io/reader "fake.txt")]
    (->> (line-seq r)
         (map parse-long)
         (map inc)
         (filter even?)
         (map inc)
         (reduce + 0))))
Enter fullscreen mode Exit fullscreen mode

F2 is the transducer-based version of F1.

(defn f2
  []
  (with-open [r (io/reader "fake.txt")]
    (transduce (comp (map parse-long)
                     (map inc)
                     (filter even?)
                     (map inc))
               +
               (line-seq r))))
Enter fullscreen mode Exit fullscreen mode

I evaluated them using Criterium.

(with-progress-reporting (quick-bench (f1) :verbose))
(with-progress-reporting (quick-bench (f2) :verbose))
Enter fullscreen mode Exit fullscreen mode

Here is the result.

#################### F1 ###################
Evaluation count : 6 in 6 samples of 1 calls.
Execution time sample mean : 3.811858 sec
Execution time mean : 3.812064 sec

#################### F2 ###################
Evaluation count : 6 in 6 samples of 1 calls.
Execution time sample mean : 1.490624 sec
Execution time mean : 1.490777 sec
Enter fullscreen mode Exit fullscreen mode

F1, which is the lazy sequence version, took 3.812064 seconds. F2, which is the transducer version, took 1.490777. So the transducer version is 155.71% faster than the lazy sequence version.

In brief, this biased experiment shows the transducer version is much faster than the pure lazy sequence version.

Top comments (0)