From bfc16ce3ab8455f173f2302bd1ebf6d0dc920dbd Mon Sep 17 00:00:00 2001 From: Peter Taoussanis Date: Thu, 13 Jun 2013 02:27:00 +0700 Subject: [PATCH] Optimize collection creation (much faster) --- src/taoensso/nippy.clj | 28 +++++++++++++--------------- src/taoensso/nippy/utils.clj | 18 ++++++++++++------ 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/src/taoensso/nippy.clj b/src/taoensso/nippy.clj index 0007207..dc82023 100644 --- a/src/taoensso/nippy.clj +++ b/src/taoensso/nippy.clj @@ -167,13 +167,13 @@ (defn coll-thaw "Thaws simple collection types." - [^DataInputStream s] - (utils/repeatedly* (.readInt s) #(thaw-from-stream s))) + [coll ^DataInputStream s] + (utils/repeatedly* coll (.readInt s) #(thaw-from-stream s))) (defn coll-thaw-kvs "Thaws key-value collection types." - [^DataInputStream s] - (utils/repeatedly* (/ (.readInt s) 2) + [coll ^DataInputStream s] + (utils/repeatedly* coll (/ (.readInt s) 2) (fn [] [(thaw-from-stream s) (thaw-from-stream s)]))) (defn- thaw-from-stream @@ -191,17 +191,15 @@ id-string (String. (read-bytes s) "UTF-8") id-keyword (keyword (.readUTF s)) - id-queue (into (PersistentQueue/EMPTY) (coll-thaw s)) - id-sorted-set (into (sorted-set) (coll-thaw s)) - id-sorted-map (into (sorted-map) (coll-thaw-kvs s)) + id-queue (coll-thaw (PersistentQueue/EMPTY) s) + id-sorted-set (coll-thaw (sorted-set) s) + id-sorted-map (coll-thaw-kvs (sorted-map) s) - ;;id-list (into '() (reverse (coll-thaw s))) - ;;id-vector (into [] (coll-thaw s)) - id-list (into '() (rseq (coll-thaw s))) - id-vector (into [] (coll-thaw s)) - id-set (into #{} (coll-thaw s)) - id-map (into {} (coll-thaw-kvs s)) - id-coll (doall (coll-thaw s)) + id-list (into '() (rseq (coll-thaw [] s))) + id-vector (coll-thaw [] s) + id-set (coll-thaw #{} s) + id-map (coll-thaw-kvs {} s) + id-coll (seq (coll-thaw [] s)) id-meta (let [m (thaw-from-stream s)] (with-meta (thaw-from-stream s) m)) @@ -221,7 +219,7 @@ ;;; DEPRECATED id-old-reader (read-string (.readUTF s)) id-old-string (.readUTF s) - id-old-map (apply hash-map (utils/repeatedly* (* 2 (.readInt s)) + id-old-map (apply hash-map (repeatedly (* 2 (.readInt s)) #(thaw-from-stream s))) (throw (Exception. (str "Failed to thaw unknown type ID: " type-id)))))) diff --git a/src/taoensso/nippy/utils.clj b/src/taoensso/nippy/utils.clj index ecdcc65..28eb549 100644 --- a/src/taoensso/nippy/utils.clj +++ b/src/taoensso/nippy/utils.clj @@ -13,12 +13,18 @@ clauses) ~(when default default)))) -(defn repeatedly* "Like `repeatedly` but faster and returns a vector." - [n f] - (loop [v (transient []) idx 0] - (if (>= idx n) - (persistent! v) - (recur (conj! v (f)) (inc idx))))) +(defn repeatedly* + "Like `repeatedly` but faster and returns given collection type." + [coll n f] + (if-not (instance? clojure.lang.IEditableCollection coll) + (loop [v coll idx 0] + (if (>= idx n) + v + (recur (conj v (f)) (inc idx)))) + (loop [v (transient coll) idx 0] + (if (>= idx n) + (persistent! v) + (recur (conj! v (f)) (inc idx)))))) (defmacro time-ns "Returns number of nanoseconds it takes to execute body." [& body] `(let [t0# (System/nanoTime)] ~@body (- (System/nanoTime) t0#)))