4

对于简单的 Javascript 对象树,是否有任何好的序列化/反序列化格式,其占用空间比 JSON 小得多?BSON不是很令人印象深刻。

JSON 中的冗余开销对于许多对象共享同一组属性的树来说尤其重要。理论上,应该可以检测对象数组中的模式,从而不重复属性名称。

4

3 回答 3

1

您可以将 JSON 转换为更多的“数据库”格式,然后将其转换回常规对象。结果有时是值得的。

// Typed on the fly
var dict = [
  ["FirstName", "LastName"],
  ["Ken",       "Starr"],
  ["Kermit",    "Frog"]
];

然后你可以循环字典,像这样:

// Again, typed on the fly
var headers = dict[0];
var result = []
var o;
for (var i = 0 + 1; i < dict.length; i++) {
  o = {}
  for (j = 0; j < headers.length; j++) {
    o[headers[j]] = dict[i][j];
  }
  result.push(o);
}
于 2013-03-20T08:50:26.810 回答
1

Gzip 速度很快。非常快。而且我非常有信心,它是精益物体运输的最佳(就实用性和效率而言)解决方案。

为了说明这一点,我在我的一个临时站点上构建了一个快速示例。

http://staging.svidgen.com/ajax/test-a.js生成 5k 行简单数据并输出原始的、未受污染的 JSON。

$data = array();
for ($i = 0; $i < 5000; $i++) {
    $data[] = array(
        'value-a' => $i,
        'value-b' => pow($i,2),
        'value-c' => pow($i,3)
    );
}

print json_encode($data);

压缩后的响应为65KB ,请求、构建、序列化和传输大约需要357 毫秒。从等式中省略客户端大小的解析,这是182KB /s的吞吐量。考虑到传输的274KB原始数据,这是767KB/s的有效吞吐量。响应如下所示:

[{"value-a":0,"value-b":0,"value-c":0},{"value-a":1,"value-b":1,"value-c":1} /* etc. */]

另一种格式http://staging.svidgen.com/ajax/test-b.js生成相同的 5k 行简单数据,但将数据重组为更高效的索引 JSON 序列化。

$data = array();
for ($i = 0; $i < 5000; $i++) {
    $data[] = array(
        'value-a' => $i,
        'value-b' => pow($i,2),
        'value-c' => pow($i,3)
    );
}

$out_index = array();
$out = array();

foreach ($data as $row) {
    $new_row = array();
    foreach ($row as $k => $v) {
        if (!isset($out_index[$k])) {
            $out_index[$k] = sizeof($out_index);
        }
        $new_row[$out_index[$k]] = $v;
    }
    $out[] = $new_row;
}

print json_encode(array(
    'index' => $out_index,
    'rows' => $out
));

压缩后的响应为59.4KB,请求、构建、序列化和传输大约需要515 毫秒。从等式中省略客户端大小解析,吞吐量115KB/s。考虑到传输的128KB原始数据,这是248KB/s的有效吞吐量。响应如下所示:

{"index":{"value-a":0,"value-b":1,"value-c":2},"rows":[[0,0,0],[1,1,1] /* etc. */ ]}

因此,在我们相当简单的示例中,重组后的原始数据比原始原始数据小 50% 以上。但是,压缩后它只小了 9%。在这种情况下,成本是总请求时间增加了 44%。

如果您编写了一个二进制库来重构数据,我希望您可以显着减少 44%。但是,它仍然不太可能值得。您需要它来序列化数据,而不需要比“正常”编码结构多 9% 的时间才能看到任何收益。

避免重组或“替代序列化”命中的唯一方法是从头到尾以笨拙的索引方式在服务器端处理所有对象。而且,除非你真的迫于压力从硬件中获得每一个可忽略不计的性能,否则这真的只是一个糟糕的主意。

在这两种情况下,gzip 节省的空间远远超出了我们使用另一种 JavaScript 可兼容格式所能达到的效果。

(而且我们甚至没有考虑客户端大小的解析——这对于任何不是“正常”JSON 或 XML 的东西都非常重要。)

综上所述

只需使用内置的序列化库和 gzip。

于 2013-04-23T15:18:14.550 回答
0
  1. 有非常快速的压缩库。因此,并不是说紧凑格式比不太紧凑的格式加压缩更好。

    我手头没有链接,但我认为一位前 protobuf 设计师推荐了这种方法。

  2. 查看MessagePack。这是一种相当紧凑的二进制格式,其语义与 JSON 或 BSON 非常相似。

    短数组(最多 16 个元素)、映射(最多 16 对)和字符串(最多 32 个字节)具有单字节开销。小整数(-32 到 128)总共只占用一个字节。

于 2013-04-23T14:14:00.297 回答