gzipの圧縮レベルと速度の関係を調べてみた

gzipってやつには圧縮レベルなんてオプションがありますが、あれと速度の関係はどんな感じなんでしょうね? 気になったので調べてみました。

テストに使ったのはpython付属のgzipライブラリ。tmpfs上でテストしたので読み書きのオーバーヘッドはかなり小さいはず。 データにはwikipediaのgzipの記事を100回繰り替えしたものを使ってみました。5.5MBくらい。 コードは末尾に。

そんなことより結果から。

圧縮レベル圧縮[秒]伸長[秒]圧縮後のサイズ圧縮率
オリジナル005,457,3001
10.05650.02331,704,9110.312
20.06100.02321,637,6680.300
30.06840.02251,599,0150.293
40.08210.02231,485,1180.272
50.10870.02221,444,2080.264
60.13920.02201,426,5540.261
70.15150.02151,422,1990.260
80.17580.02141,418,4810.259
90.17720.02151,418,4810.259

レベルが上がると圧縮の時間が伸びるけれど、伸長は変わらない。

グラフ化するとこんな感じ。

gzipの圧縮レベルと圧縮時間の関係

gzipの圧縮レベルと伸長時間の関係

gzipの圧縮レベルと圧縮率の関係

上から順に圧縮にかかる時間、伸長にかかる時間、圧縮率。

圧縮レベル6を越えたあたりから時間がかかるばっかで圧縮率が変わらない。不毛な感じ。 レベルが上がるにつれて伸長にかかる時間が若干減ってるのは・・・何だろう? IO関連か?

こうやってみると、大抵デフォルトに設定されてるレベル6ってのは実にバランス取れてるんだなぁと思ったり。

テスト用に使ったコードはこんな感じ。

import gzip
import timeit
import urllib.request

TRY = 100
DATA = urllib.request.urlopen('http://ja.wikipedia.org/wiki/Gzip').read() * 100


def comp(level):
    with gzip.open('test.gz', 'wb', compresslevel=level) as fp:
        fp.write(DATA)


def decomp():
    with gzip.open('test.gz', 'rb') as fp:
        fp.read()


if __name__ == '__main__':
    print('level\tcomp\tdecomp\tsize')
    print('original\t0\t0\t{0}'.format(len(DATA)))
    for i in range(1, 10):
        co = timeit.timeit(lambda : comp(i), number=TRY)/TRY
        size = len(open('test.gz', 'rb').read())
        de = timeit.timeit(decomp, number=TRY)/TRY
        print('{0}\t{1}\t{2}\t{3}'.format(i, co, de, size))

同じ圧縮レベルをまとめて試すのは本当はよくないんだろうけれど、まあ面倒くさいので。