From 5492c1ea0f3d2defbe9d514f05a9f1d11856001b Mon Sep 17 00:00:00 2001 From: Zach Tellman Date: Wed, 9 Oct 2013 23:54:02 -0400 Subject: [PATCH] don't iterate twice over uncounted seqs, and use explicit key/val accessors for kv-collections, appears to give ~25% improvement in 'freeze' --- src/taoensso/nippy.clj | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/taoensso/nippy.clj b/src/taoensso/nippy.clj index c4c8f83..ce55eac 100644 --- a/src/taoensso/nippy.clj +++ b/src/taoensso/nippy.clj @@ -114,17 +114,30 @@ "Extends Freezable to simple collection types." [type id & body] `(freezer ~type ~id - (.writeInt ~'s (count ~'x)) - (doseq [i# ~'x] (freeze-to-stream ~'s i#)))) + (if (counted? ~'x) + (do + (.writeInt ~'s (count ~'x)) + (doseq [i# ~'x] (freeze-to-stream ~'s i#))) + (let [bas# (ByteArrayOutputStream.) + s# (DataOutputStream. bas#) + cnt# (reduce + (fn [cnt# i#] + (freeze-to-stream! s# i#) + (unchecked-inc cnt#)) + 0 + ~'x) + ba# (.toByteArray bas#)] + (.writeInt ~'s cnt#) + (.write ~'s ba# 0 (alength ba#)))))) (defmacro ^:private kv-freezer "Extends Freezable to key-value collection types." [type id & body] `(freezer ~type ~id (.writeInt ~'s (* 2 (count ~'x))) - (doseq [[k# v#] ~'x] - (freeze-to-stream ~'s k#) - (freeze-to-stream ~'s v#)))) + (doseq [kv# ~'x] + (freeze-to-stream ~'s (key kv#)) + (freeze-to-stream ~'s (val kv#))))) (freezer (Class/forName "[B") id-bytes (write-bytes s ^bytes x)) (freezer nil id-nil)