PandasのDataFrameをPickle化したものを圧縮するというユースケースにおいてデータ容量毎(約10MB、約100MB、約1GBの3パターン)に圧縮(compress)・解凍(decompress)の速度と圧縮率を比較しました。
※本記事ではzlib、gzip、bz2の実用面での評価を目的にしたものです。アルゴリズムそのものについては他のサイトなどをご参考ください。
「圧縮と解凍の速度はzlibがbz2より速く、ぞれぞれ約25倍・約8倍速い。一方で圧縮率はbz2がzlibの約30倍高い。」ということが解りました。
目次
比較結果
計測結果です。(後述のコードの出力結果をサマリしたものです)
元 fileSize [MB] | 平均 / zlib.compress_time [秒] | 平均 / gzip.compress_time [秒] | 平均 / bz2.compress_time [秒] | 平均 / zlib.decompress_time [秒] | 平均 / gzip.decompress_time [秒] | 平均 / bz2.decompress_time [秒] | zlibのデータ圧縮率 | gzipのデータ圧縮率 | bz2のデータ圧縮率 |
---|---|---|---|---|---|---|---|---|---|
10.3 | 0.05813 | 0.0629 | 1.53769 | 0.01165 | 0.01713 | 0.0835 | 0.151% | 0.151% | 0.009% |
103.0 | 0.56849 | 0.61646 | 14.89975 | 0.10041 | 0.21076 | 0.85508 | 0.146% | 0.146% | 0.005% |
1030.0 | 5.97795 | 6.1698 | 152.46163 | 1.13844 | 4.2695 | 8.85216 | 0.146% | 0.146% | 0.004% |
圧縮速度、解凍速度、圧縮率の比較は下記の通りです。
圧縮速度(*.compress_time):zlib > gzip >> bz2
解凍速度(*.decompress_time):zlib > gzip >> bz2
データ圧縮率:bz2 >> zlib≒gzip ※とはいえ zlib・gzip でも0.15%程度には圧縮できている
圧縮アルゴリズム(zlib、gzip、bz2)の速度比較
速度と容量の計測に使用したコードです。そのまま実行可能です。
zlib、gzip、bz2それぞれの compress() と decompress() の速度比較を行っています。
import numpy as np
import pandas as pd
import os
import time
import pickle
import zlib
import gzip
import bz2
import gc
class StopWatch:
'''
sw = StopWatch()
sw.start()
print(f"*** 処理時間:{sw.stop()}")
'''
def start(self):
self.__starttime = time.time()
self.__time = 0
return
def stop(self):
self.__time = time.time() - self.__starttime
return self.__time
def gettime(self):
return self.__time
def objectsize(_obj):
return round(_obj.__sizeof__()/(1024*1024),5)
def objectsizePrint(_obj):
print(f" オブジェクトサイズ = {objectsize(_obj)}MB")
def compressAndDecompress(_object, _algo, _name):
print(f"■{_name}")
sw = StopWatch()
try:
sw.start()
_compressed = _algo.compress(_object)
print(f"{_name}.compress:{sw.stop()}")
objectsizePrint(_compressed)
_rec.append(sw.gettime())
_rec.append(objectsize(_compressed))
except:
_rec.append("Err")
_rec.append("Err")
_compressed = ""
try:
sw.start()
_decompressed = _algo.decompress(_compressed)
print(f"{_name}.decompress:{sw.stop()}")
objectsizePrint(_decompressed)
_rec.append(sw.gettime())
except:
_rec.append("Err")
del _compressed
del _decompressed
gc.collect()
if __name__ == "__main__":
sw = StopWatch()
kekka = []
_colN = 45
for i in [3,30,300]:
N = i*10000
print(f"■{N/10000}万行{_colN}列----------")
for j in range(5):
_rec = []
_rec.append(N)
_rec.append(j+1)
print(f"■■計測{j+1}回目----------")
try:
df = pd.DataFrame(np.ones((N,_colN)))
df_pickled = pickle.dumps(df)
objectsizePrint(df_pickled)
_rec.append(objectsize(df_pickled))
except:
_rec.append("Err")
compressAndDecompress(df_pickled, zlib, "zlib")
compressAndDecompress(df_pickled, gzip, "gzip")
compressAndDecompress(df_pickled, bz2, "bz2")
kekka.append(_rec)
#print(kekka)
dfkekka = pd.DataFrame(kekka)
dfkekka.columns = [
'length', "times", 'fileSize',
"zlib.compress_time", "zlib.compress_size","zlib.decompress_time",
"gzip.compress_time", "gzip.compress_size","gzip.decompress_time",
"bz2.compress_time", "bz2.compress_size","bz2.decompress_time"
]
dfkekka.to_csv('compose_decompose.csv')
Google Colaboratory で実行する
先述のコードは Googl Colaboratory から直接実行できます。
また、実行結果は Pandas.DataFrame に格納しておりますので下記などを参考に分析・可視化して頂ければと思います。
まとめ
本記事では、圧縮アルゴリズム(zlib、gzip、bz2)の速度比較を行いました。
ご参考になりましたら twitter をフォローして SNS でシェアして頂ければ幸いです。
IT・プログラミングに関する相談・依頼はこちら