6

JSON 和 Gzip 是一种序列化数据的简单方法。这些在编程语言中被广泛实现。这种表示形式也可以跨系统移植(是吗?)。

我的问题是与非常有效的二进制序列化方法相比,json+gzip 是否足够好(低于 2 倍的成本)?我在序列化各种数据时寻找空间和时间成本。

4

1 回答 1

9

对于数字和对象,使用 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
于 2016-03-07T14:08:58.157 回答