Created
April 16, 2022 19:10
-
-
Save leonoel/7e6cb47399f6fc7d387e393e2d7de74a to your computer and use it in GitHub Desktop.
cloroutine performance
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns ^{:doc " | |
Performance measurements for various generator implementations, cloroutine v10 https://github.com/leonoel/cloroutine | |
Based on https://clojureverse.org/t/how-to-transform-nested-map-into-flat-sequence-of-path-value-pairs/8801/22 | |
"} cloroutine-perf | |
(:require [cloroutine.core :refer [cr]])) | |
(def ^:dynamic *tail*) | |
(defn gen-seq-dv [gen] | |
(lazy-seq (binding [*tail* (gen-seq-dv gen)] (gen)))) | |
(defn yield-seq-dv [x] | |
(cons x *tail*)) | |
(defn no-op []) | |
(defmacro generator-seq-dv [& body] | |
`(gen-seq-dv (cr {yield-seq-dv no-op} ~@body nil))) | |
(let [tl (ThreadLocal.)] | |
(defn gen-seq-tl [gen] | |
(lazy-seq | |
(let [prev (.get tl)] | |
(.set tl (gen-seq-tl gen)) | |
(try (gen) (finally (.set tl prev)))))) | |
(defn yield-seq-tl [x] | |
(cons x (.get tl)))) | |
(defmacro generator-seq-tl [& body] | |
`(gen-seq-tl (cr {yield-seq-tl no-op} ~@body nil))) | |
(defn gen-reduce [ctor] | |
(reify | |
clojure.lang.IReduceInit | |
(reduce [_ f i] | |
(let [gen (ctor)] | |
(loop [r i] | |
(if (reduced? r) | |
@r (let [x (gen)] | |
(case x | |
::done r | |
(recur (f r x)))))))) | |
java.lang.Iterable | |
(iterator [_] | |
(let [gen (ctor) | |
cur (clojure.lang.Box. (gen))] | |
(reify java.util.Iterator | |
(next [_] | |
(let [x (.-val cur)] | |
(set! (.-val cur) (gen)) x)) | |
(hasNext [_] (not= ::done (.-val cur)))))))) | |
(def yield-reduce identity) | |
(defmacro generator-reduce [& body] | |
`(gen-reduce #(cr {yield-reduce no-op} ~@body ::done))) | |
(defn last-rf | |
([]) | |
([r] r) | |
([_ x] x)) | |
(comment | |
;; lazy-seq, cloroutine with dynamic var (tutorial implemention) | |
(time (dotimes [i 10] (last (take 1000000 (generator-seq-dv (loop [] (yield-seq-dv :a) (recur))))))) | |
"Elapsed time: 5420.276562 msecs" | |
;; lazy-seq, cloroutine with thread local | |
(time (dotimes [i 10] (last (take 1000000 (generator-seq-tl (loop [] (yield-seq-tl :a) (recur))))))) | |
"Elapsed time: 1573.082021 msecs" | |
;; lazy-seq, naive implementation | |
(time (dotimes [i 10] (last (take 1000000 ((fn repeat-l [x] (lazy-seq (cons x (repeat-l x)))) :a))))) | |
"Elapsed time: 1132.88954 msecs" | |
;; lazy-seq, core implementation | |
(time (dotimes [i 10] (last (take 1000000 (repeat :a))))) | |
"Elapsed time: 896.978254 msecs" | |
;; reducible, cloroutine | |
(time (dotimes [i 10] (transduce (take 1000000) last-rf (generator-reduce (loop [] (yield-reduce :a) (recur)))))) | |
"Elapsed time: 357.013956 msecs" | |
;; reducible, core implementation | |
(time (dotimes [i 10] (transduce (take 1000000) last-rf (repeat :a)))) | |
"Elapsed time: 166.334069 msecs" | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment