我刚刚重新运行了我的性能测试。 msgpack、feather 和 parquet 已更改接口或已删除,因此不再工作。
我的用例更多地是围绕使用哪种序列化格式来缓存 Redis 缓存中的数据帧。没有明显的赢家
- 使用 pickle 可以,但您会收到来自 pandas 的弃用警告,并且确实保持向后兼容性。这是一种仅限 python 的序列化格式
- 使用 pyarrow 提供了更多的可移植性,可以在 python、java、...中使用。但是它不保持跨版本的向后兼容性ARROW-7961
- 是否再次压缩是基于空间/时间权衡的决定
我继续使用pyarrow 并对此感到满意。但是,如果发现暂时的向后兼容性问题,我的代码将自动切换到 pickle。
import sys, pickle, zlib, warnings, io
import pyarrow as pa
t = list(pd.date_range(dt.datetime(2020,1,1), dt.datetime(2020,1,3), freq='min'))
uh = [random.randint(0,50) for e in t]
out = pd.DataFrame({"timestamp":t, "user_holding":uh})
class foocls:
def pyarrow(out): return pa.serialize(out).to_buffer().to_pybytes()
# def msgpack(out): return out.to_msgpack()
def pickle(out): return pickle.dumps(out)
# def feather(out): return out.to_feather(path=io.BytesIO())
# def parquet(out): return out.to_parquet(io.BytesIO())
warnings.filterwarnings("ignore")
for c in foocls.__dict__.values():
sbreak = True
try:
c(out)
print(c.__name__, "before serialization", sys.getsizeof(out))
print(c.__name__, sys.getsizeof(c(out)))
%timeit -n 50 c(out)
print(c.__name__, "zlib", sys.getsizeof(zlib.compress(c(out))))
%timeit -n 50 zlib.compress(c(out))
except TypeError as e:
if "not callable" in str(e): sbreak = False
else: raise
except (ValueError) as e: print(c.__name__, "ERROR", e)
finally:
if sbreak: print("=+=" * 30)
warnings.filterwarnings("default")
输出
pyarrow before serialization 46256
pyarrow 51901
630 µs ± 59.9 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
pyarrow zlib 20041
2.72 ms ± 53.2 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=
pickle before serialization 46256
pickle 47166
96.7 µs ± 5.02 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
pickle zlib 19276
1.95 ms ± 25.3 µs per loop (mean ± std. dev. of 7 runs, 50 loops each)
=+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+==+=