词典数据的压缩方式比较
(没写完,待探究的细节过多,待续)
最近在重构WudaoDict,从作者这里还真学到一些东西,比如词典数据的压缩方式。他的本地数据文件是这样的:
1
2
3
4
-rw-r--r-- 1 k k 1.7M Nov 19 2018 en.ind
-rw-r--r-- 1 k k 1.2M Nov 19 2018 zh.ind
-rw-r--r-- 1 k k 44M Nov 19 2018 en.z
-rw-r--r-- 1 k k 37M Nov 19 2018 zh.z
两个z文件是大约两万个词条用zlib压缩后的二进制拼接,ind则记录了将近两万个中英文词条的索引(文件偏移量),每次查词时实时根据索引去给z文件切块,然后读文件、zlib解压再decode。
粗看很不以为然,但我自己试了几种方式,却无法达到更好的压缩效果,看到release日志中特地提到压缩空间的改进,想必作者当初也费了一番功夫探究。
我最开始没有考虑过空间的问题,设想的方案是直接存JSON文件或sqlite,结果今天晚上我的IP突然被youdao给禁了,我不得不开始考虑构建本地词库。我用他的这两个z文件数据模拟了几种最粗糙的存储方式,
介质 | 方式 | 大小 |
---|---|---|
sqlite3 | 解码,拆分字段后存入 | 71M |
sqlite3 | 解码,作为单独长字符串字段 | 72M |
sqlite3 | 不解码,作为单独长字符串字段 | 72M |
文本文件 | 解码,存入单文件 | 61M |
介质 | 方式 | 大小 |
---|---|---|
sqlite3 | 扩充字段的JSON | 204M |
变更压缩方式
序列化方式 | 版本/参数 | 方式 | 大小 |
---|---|---|---|
pickle | dump对象->Bytes | 120M | |
cbor | cbor2 | dump对象->Bytes | 120M |
msgpack | dump对象->Bytes | 102M | |
gzip | 压缩JSON->Bytes | 63M | |
zlib | level 9 | 压缩JSON->Bytes | 61M |
msgpack+zlib | level 9 | dump对象后压缩>Bytes | 58M |
初步猜测是数据增加了大量的标点符号,而zlib的压缩方式
暂定
加入codec之后编译binary大小增加1M,且数据结构要重写一个MsgPack版本
Reference
- https://medium.com/@u.praneel.nihar/improving-read-write-store-performance-by-changing-file-formats-serialization-protocols-bfdb13114004
- http://zderadicka.eu/comparison-of-json-like-serializations-json-vs-ubjson-vs-messagepack-vs-cbor/
- https://devforum.roblox.com/t/string-compression-zlibdeflate/755687
This post is licensed under CC BY 4.0 by the author.