From 3879cf4d6263c1938e8463ece771dbccf79ec32b Mon Sep 17 00:00:00 2001 From: Peter Taoussanis Date: Sat, 19 Oct 2013 12:49:45 +0700 Subject: [PATCH] Add experimental LZMA2 compressor for higher compression ratios than Snappy --- benchmarks.png | Bin 23474 -> 21083 bytes project.clj | 3 +- src/taoensso/nippy/benchmarks.clj | 85 ++++++++++++----------------- src/taoensso/nippy/compression.clj | 48 +++++++++++++++- test/taoensso/nippy/tests/main.clj | 13 ++++- 5 files changed, 94 insertions(+), 55 deletions(-) diff --git a/benchmarks.png b/benchmarks.png index 7775781800b465fc0f101eb288bfd28e5d53f2c8..ffd885827075ad9c290d81a169292d3d52e9f351 100644 GIT binary patch literal 21083 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 literal 23474 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 diff --git a/project.clj b/project.clj index 6e34868..22ffe2a 100644 --- a/project.clj +++ b/project.clj @@ -5,7 +5,8 @@ :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[org.clojure/clojure "1.4.0"] [org.clojure/tools.reader "0.7.8"] - [org.iq80.snappy/snappy "0.3"]] + [org.iq80.snappy/snappy "0.3"] + [org.tukaani/xz "1.4"]] :profiles {:1.4 {:dependencies [[org.clojure/clojure "1.4.0"]]} :1.5 {:dependencies [[org.clojure/clojure "1.5.1"]]} :1.6 {:dependencies [[org.clojure/clojure "1.6.0-master-SNAPSHOT"]]} diff --git a/src/taoensso/nippy/benchmarks.clj b/src/taoensso/nippy/benchmarks.clj index eeff3a9..9dfafad 100644 --- a/src/taoensso/nippy/benchmarks.clj +++ b/src/taoensso/nippy/benchmarks.clj @@ -2,69 +2,56 @@ {:author "Peter Taoussanis"} (:require [clojure.tools.reader.edn :as edn] [taoensso.nippy :as nippy :refer (freeze thaw)] - [taoensso.nippy.utils :as utils])) + [taoensso.nippy.compression :as compression] + [taoensso.nippy.utils :as utils])) ;; Remove stuff from stress-data that breaks reader (def data (dissoc nippy/stress-data :queue :queue-empty :bytes)) -(defmacro bench* [& body] `(utils/bench 10000 (do ~@body) :warmup-laps 2000)) +(defmacro bench* [& body] `(utils/bench 10000 (do ~@body) :warmup-laps 20000)) +(defn bench1 [freezer thawer & [sizer]] + (let [data-frozen (freezer data) + time-freeze (bench* (freezer data)) + time-thaw (bench* (thawer data-frozen))] + {:round (+ time-freeze time-thaw) + :freeze time-freeze + :thaw time-thaw + :size ((or sizer count) data-frozen)})) -(defn freeze-reader [x] (pr-str x)) -(defn thaw-reader [x] (edn/read-string x)) -(def roundtrip-reader (comp thaw-reader freeze-reader)) - -(def roundtrip-defaults (comp thaw freeze)) -(def roundtrip-encrypted (comp #(thaw % {:password [:cached "p"]}) - #(freeze % {:password [:cached "p"]}))) -(def roundtrip-fast (comp thaw #(freeze % {:compressor nil}))) - -(defn bench [{:keys [reader? laps] :or {reader? true laps 1}}] - (println) - (println "Benching (this can take some time)") +(defn bench [{:keys [reader? lzma2? laps] :or {laps 1}}] + (println "\nBenching (this can take some time)") (println "----------------------------------") (dotimes [l laps] - (println) - (println (str "Lap " (inc l) "/" laps "...")) + (println (str "\nLap " (inc l) "/" laps "...")) - (when reader? - (println - {:reader - {:round (bench* (roundtrip-reader data)) - :freeze (bench* (freeze-reader data)) - :thaw (let [frozen (freeze-reader data)] (bench* (thaw-reader frozen))) - :data-size (count (.getBytes ^String (freeze-reader data) "UTF-8"))}})) + (when reader? ; Slow + (println {:reader (bench1 #(pr-str %) #(edn/read-string %) + #(count (.getBytes ^String % "UTF-8")))})) - (println - {:defaults - {:round (bench* (roundtrip-defaults data)) - :freeze (bench* (freeze data)) - :thaw (let [frozen (freeze data)] (bench* (thaw frozen))) - :data-size (count (freeze data))}}) + (println {:default (bench1 #(freeze % {}) + #(thaw % {}))}) + (println {:encrypted (bench1 #(freeze % {:password [:cached "p"]}) + #(thaw % {:password [:cached "p"]}))}) + (println {:fast (bench1 #(freeze % {:compressor nil}) + #(thaw % {:compressor nil}))}) - (println - {:encrypted - {:round (bench* (roundtrip-encrypted data)) - :freeze (bench* (freeze data {:password [:cached "p"]})) - :thaw (let [frozen (freeze data {:password [:cached "p"]})] - (bench* (thaw frozen {:password [:cached "p"]}))) - :data-size (count (freeze data {:password [:cached "p"]}))}}) + (when lzma2? ; Slow as molasses + (println {:lzma2 (bench1 #(freeze % {:compressor compression/lzma2-compressor}) + #(thaw % {:compressor compression/lzma2-compressor}))}))) - (println - {:fast - {:round (bench* (roundtrip-fast data)) - :freeze (bench* (freeze data {:compressor nil})) - :thaw (let [frozen (freeze data {:compressor nil})] - (bench* (thaw frozen))) - :data-size (count (freeze data {:compressor nil}))}})) - - (println) - (println "Done! (Time for cake?)") + (println "\nDone! (Time for cake?)") true) (comment - ;; (bench {:reader? true :laps 2}) - ;; (bench {:reader? false :laps 1}) - ;; (bench {:reader? false :laps 2}) + ;; (bench {:reader? true :lzma2? true :laps 1}) + ;; (bench {:laps 2}) + + ;;; 19 Oct 2013: Nippy v2.3.0, with lzma2 & (nb!) round=freeze+thaw + ;; {:reader {:round 67798, :freeze 23202, :thaw 44596, :size 22971}} + ;; {:default {:round 3632, :freeze 2349, :thaw 1283, :size 12369}} + ;; {:encrypted {:round 6970, :freeze 4073, :thaw 2897, :size 12388}} + ;; {:fast {:round 3294, :freeze 2109, :thaw 1185, :size 13277}} + ;; {:lzma2 {:round 145301, :freeze 123650, :thaw 21651, :size 9024}} ;;; 11 Oct 2013: Nippy v2.2.0, with both ztellman mods ;; {:defaults {:round 4319, :freeze 2950, :thaw 1446, :data-size 12369}} diff --git a/src/taoensso/nippy/compression.clj b/src/taoensso/nippy/compression.clj index e5e895e..457affb 100644 --- a/src/taoensso/nippy/compression.clj +++ b/src/taoensso/nippy/compression.clj @@ -1,7 +1,9 @@ (ns taoensso.nippy.compression "Alpha - subject to change." {:author "Peter Taoussanis"} - (:require [taoensso.nippy.utils :as utils])) + (:require [taoensso.nippy.utils :as utils]) + (:import [java.io ByteArrayInputStream ByteArrayOutputStream DataInputStream + DataOutputStream])) ;;;; Interface @@ -16,5 +18,45 @@ (compress [_ ba] (org.iq80.snappy.Snappy/compress ba)) (decompress [_ ba] (org.iq80.snappy.Snappy/uncompress ba 0 (alength ^bytes ba)))) -(def snappy-compressor "Default org.iq80.snappy.Snappy compressor." - (->SnappyCompressor)) \ No newline at end of file +(def snappy-compressor + "Default org.iq80.snappy.Snappy compressor: + Ratio: low. + Write speed: very high. + Read speed: very high. + + A good general-purpose compressor for Redis." + (->SnappyCompressor)) + +(deftype LZMA2Compressor [compression-level] + ;; Compression level ∈ℕ[0,9] (low->high) with 6 LZMA2 default (we use 4) + ICompressor + (compress [_ ba] + (let [ba-len (alength ^bytes ba) + ba-os (ByteArrayOutputStream.) + ;; Prefix with uncompressed length: + _ (.writeInt (DataOutputStream. ba-os) ba-len) + xzs (org.tukaani.xz.XZOutputStream. ba-os + (org.tukaani.xz.LZMA2Options. compression-level))] + (.write xzs ^bytes ba) + (.close xzs) + (.toByteArray ba-os))) + + (decompress [_ ba] + (let [ba-is (ByteArrayInputStream. ba) + ba-len (.readInt (DataInputStream. ba-is)) + ba (byte-array ba-len) + xzs (org.tukaani.xz.XZInputStream. ba-is)] + (.read xzs ba 0 ba-len) + (when (not= -1 (.read xzs)) ; Good practice as extra safety measure + (throw (Exception. "LZMA2 Decompress failed: corrupt data?"))) + ba))) + +(def lzma2-compressor + "Alpha - subject to change. + Default org.tukaani.xz.LZMA2 compressor: + Ratio: high. + Write speed: very slow. + Read speed: medium. + + A specialized compressor for large, low-write, high-read data." + (->LZMA2Compressor 4)) diff --git a/test/taoensso/nippy/tests/main.clj b/test/taoensso/nippy/tests/main.clj index a9d0344..4a70bcf 100644 --- a/test/taoensso/nippy/tests/main.clj +++ b/test/taoensso/nippy/tests/main.clj @@ -1,7 +1,8 @@ (ns taoensso.nippy.tests.main (:require [expectations :as test :refer :all] [taoensso.nippy :as nippy :refer (freeze thaw)] - [taoensso.nippy.benchmarks :as benchmarks])) + [taoensso.nippy.compression :as compression] + [taoensso.nippy.benchmarks :as benchmarks])) ;; Remove stuff from stress-data that breaks roundtrip equality (def test-data (dissoc nippy/stress-data :bytes)) @@ -14,6 +15,14 @@ (expect test-data ((comp #(thaw % {:password [:salted "p"]}) #(freeze % {:password [:salted "p"]})) test-data)) +(expect test-data ((comp #(thaw % {:compressor compression/lzma2-compressor}) + #(freeze % {:compressor compression/lzma2-compressor})) + test-data)) +(expect test-data ((comp #(thaw % {:compressor compression/lzma2-compressor + :password [:salted "p"]}) + #(freeze % {:compressor compression/lzma2-compressor + :password [:salted "p"]})) + test-data)) (expect AssertionError (thaw (freeze test-data {:password "malformed"}))) (expect Exception (thaw (freeze test-data {:password [:salted "p"]}))) @@ -46,4 +55,4 @@ (nippy/extend-thaw 2 [s] (->MyRec (.readUTF s))) (= (->MyRec "fast-val") (thaw (freeze (->MyRec "val")))))) -(expect (benchmarks/bench {:reader? false})) ; Also tests :cached passwords \ No newline at end of file +(expect (benchmarks/bench {})) ; Also tests :cached passwords