gzip圧縮 - 計時

冬休みに作成したgzip圧縮器を整理*1して、パッケージにまとめた。
deflate(0.1.0) ※ 依存: common-utils


以下は簡単な計時など。
比較対象は、gzipコマンドとcommon lispのsalza2パッケージ。

# gzip
> time gzip -c /path/to/file > file.gz
;; salza2
(time (salza2:gzip-file "/path/to/file" "file.gz"))

;; deflate
(time (deflate:gzip-file "/path/to/file" "file.gz"))



gzip圧縮】『こころ』*2の圧縮時間/圧縮サイズ(圧縮率)bashコマンドの...IPA辞書*3の...
gzipコマンド0.054s/170KB(31.4%)0.057s/335KB(48.8%)1.141s/5.6MB(18.7%)
deflate0.071s/188KB(34.6%)0.083s/351KB(51.1%)2.774s/6.1MB(20.2%)
salza2*40.063s/261KB(48.2%)0.086s/402KB(58.6%)2.584s/7.5MB(24.9%)
clojure
※追記2
0.072s/171KB(31.4%)0.079s/334KB(48.6%)1.684s/5.6MB(18.7%)

やっぱりgzipコマンドは優秀。


ただ、common lisp(sbcl)で実装 + 作成期間が一週間程度、ということを考えればdeflateパッケージも性能的には悪くはないと思う。

###

当初はgzip解凍器も作成する予定だったが、そのために時間を割くよりは、別の圧縮アルゴリズムを勉強したいので保留としておく。

追記(2010/01/11)

ちなみに、急に思い立ちAllegro Common Lisp(Express Edition)をインストール*5して、同様に『こころ』に対するgzip圧縮の所要時間を計測してみたところ、約1.7秒掛かった。


sbcl用の最適化じゃ駄目か...。

追記2(2010/01/11)

clojure(ほとんどJava)も追加。

(import '(java.io FileOutputStream FileInputStream)
        '(java.util.zip GZIPOutputStream))

(defn gzip-file [in-file out-file]
  (let [in  (new FileInputStream in-file)
        out (new GZIPOutputStream
                 (new FileOutputStream out-file))
        buf (make-array Byte/TYPE 4096)]
    (letfn [(write-loop [len]
              (when (not (= len -1))
                (.write out buf 0 len)
                (recur (.read in buf))))]
      (write-loop (.read in buf)))
    (.close in)
    (.close out)
    'DONE))

;; 
(gzip-file "/path/to/file" "file.gz")

*1:実際にはほとんど作り直し。ただし、ソースの全体の構造は、以前の記事に載せたものとほとんど変わっていない

*2:夏目漱石著、青空文庫より取得、UTF-8

*3:MeCabのサイトより取得、*.csvEUC-JP

*4:固定ハフマン符号を用いた圧縮にのみ対応。圧縮処理時のコンス量がすごく少ない(ほとんどの場合GCが走らない)。

*5:common-utilsパッケージのインストールで若干手間取る。flatten関数の定義をコメントアウトして対処。