JSON 和 Gzip 是一种序列化数据的简单方法。这些在编程语言中被广泛实现。这种表示形式也可以跨系统移植(是吗?)。
我的问题是与非常有效的二进制序列化方法相比,json+gzip 是否足够好(低于 2 倍的成本)?我在序列化各种数据时寻找空间和时间成本。
JSON 和 Gzip 是一种序列化数据的简单方法。这些在编程语言中被广泛实现。这种表示形式也可以跨系统移植(是吗?)。
我的问题是与非常有效的二进制序列化方法相比,json+gzip 是否足够好(低于 2 倍的成本)?我在序列化各种数据时寻找空间和时间成本。
对于数字和对象,使用 json+gzip 进行序列化使用的空间比 rawbytes+gzip 多 25%。对于有限精度数字(4 个有效数字),序列化大小是相同的。看来对于小规模的应用,就数据量而言,使用 json+gzip 就足够了。即使在发送记录数组时也是如此,其中每条记录完全拼写出字段和值(在 JavaScript 中存储数据的常用方式)。
以下实验来源:https ://github.com/csiz/gzip-json-performance
我选择了一百万个浮点(64 位)数字。我假设这些数字来自一些自然来源,所以我使用指数分布来生成它们,然后将它们四舍五入到 4 位有效数字。因为 JSON 写下了整个表示,我认为存储大量数字可能会产生更大的成本(例如,存储 123456.000000,与 0.123456),所以我检查了这两种情况。我还检查了尚未四舍五入的序列号。
序列化小数字时,压缩 json 使用的大小比压缩二进制大 9%(数量级约为 1.0,因此只需写下几位数字):
json 3.29mb json/raw 43%
binary 3.03mb binary/raw 40%
json/binary 1.09
序列化大数字时,压缩 json 使用的大小比压缩二进制小 17%(数量级约为 1000000,要写下更多数字):
json 2.58mb json/raw 34%
binary 3.10mb binary/raw 41%
json/binary 0.83
序列化全精度双精度时,压缩 json 使用的大小比压缩二进制大 22%:
json 8.90mb json/raw 117%
binary 7.27mb binary/raw 95%
json/binary 1.22
对于对象,我以 JSON 中通常的惰性方式对它们进行序列化。每个对象都存储为带有字段名称和值的完整记录。“选择”枚举的价值已被充分阐明。
[
{
"small number": 0.1234,
"large number": 1234000,
"choice": "two"
},
...
]
而对于有效的二进制表示,我将对象矢量化。我存储对象的数量,然后是小数字的连续向量,然后是选择枚举的连续向量。在这种情况下,我假设枚举值是已知且固定的,因此我将索引存储到此枚举中。
n = 1e6
small number = binary([0.1234, ...])
large number = binary([1234000, ...])
choice = binary([2, ...]) # indexes to the enum ["zero", "one", ..., "four"]
存储对象时,压缩 json 使用的大小比压缩二进制大 27%:
json 8.36mb json/raw 44%
binary 6.59mb binary/raw 35%
json/binary 1.27