为什么 JSON 在 node.js 中比 BSON 快?

Why is JSON faster than BSON in node.js?

看完this,有一句话脱颖而出:

BSON is also designed to be fast to encode and decode. For example, integers are stored as 32 (or 64) bit integers, so they don't need to be parsed to and from text. This uses more space than JSON for small integers, but is much faster to parse.

根据我正在阅读的内容,使用 BSON 的全部意义在于它对 CPU 的负担较小,并且对 encode/process 的影响更快。

但是,我用 Node.js 做了一些测试,使用原生 JSON 方法使 BSON 完全失败。一些测试显示 JSON 大约快 3 到 5 倍。 (使用更多数据类型时大约为 6 到 8。)

基准代码:

var bson = require('bson');
var BSON = new bson.BSONPure.BSON();

var os = require('os');

console.log(" OS: " + os.type() + " " + os.release() + " (" + os.arch() + ")");
console.log("RAM: " + os.totalmem() / 1048576 + " MB (total), " + os.freemem() / 1048576 + " MB (free)");
console.log("CPU: " + os.cpus()[0].speed + " MHz " + os.cpus()[0].model);

for (var r = 1; r < 4; r++) {
    console.log("\nRun #" + r + ":");
    var obj = {
        'abcdef': 1,
        'qqq': 13,
        '19': [1, 2, 3, 4]
    };

    var start = Date.now();
    for (var i = 0; i < 500000; i++) {
        JSON.parse(JSON.stringify(obj));
    }
    var stop = Date.now();
    console.log("\t      JSON: " + (stop - start) + " ms");

    start = Date.now();
    for (var i = 0; i < 500000; i++) {
        BSON.deserialize(BSON.serialize(obj));
    }
    stop = Date.now();
    console.log("\t      Bson: " + (stop - start) + " ms");
}

结果:

OS: Windows_NT 6.1.7601 (x64)
RAM: 8174.1171875 MB (total), 5105.03515625 MB (free)
CPU: 3515 MHz AMD FX(tm)-6300 Six-Core Processor

Run #1:
              JSON: 1820 ms
              Bson: 8639 ms

Run #2:
              JSON: 1890 ms
              Bson: 8627 ms

Run #3:
              JSON: 1882 ms
              Bson: 8692 ms

话虽如此,我正在寻找一种二进制方法来通过 websockets 发送和接收数据。 BSON 完美地做到了这一点,但是,当查看基准测试结果时,当序列化/反序列化对象需要更长的时间时,BSON 如何能够减少 CPU 的负担?

BSON 是否弥补了它使用的额外 CPU 用法,因为不会使用 基于文本的 websockets 转换为 UTF-8?这会平衡这方面的表现吗?

@Joe Clay 下面,这里是 stringifyserializing 的结果:

Run #1:
              JSON: 922 ms
              Bson: 355 5ms

我认为你不能仅仅通过看serialise/deserialize来判断性能。您只是为 BSON 选择了错误的用例。 BSON 在数据库中大放异彩——您可以在数据库中对数据进行计算,而无需序列化它们。存储和检索二进制数据(例如图像)也使 BSON 更加高效,因为您不需要将数据编码为 Hex/BASE64 或类似的。

尝试直接对 retrieving/storing JSON 和 BSON 中的值进行一些计算。但是使用随机访问(不总是相同的项目),这样它在引擎盖下被优化的机会很小。

我相信 Node.js 大多数浏览器都是例外。

简单的答案是 JSON parser/serializer/deserializer(即 V8)经过极度优化并用 C/C++ 编写。 BSON 解析器是用 JavaScript 编写的。但即使解析器是原生编写的(我相信 BSON 有一个)JSON 仍然可能会获胜,因为 V8 是如何针对 JSON.

进行优化的

如果您使用像 Java 或 C# 这样的平台,BSON 格式可能会更快。

请参阅@Matthais247,他在我之后回答但更完整。

问题不应该是Why is JSON faster than BSON?而是Why is JSON fast than BSON in node.js?.

在大多数环境中,BSON、MessagePack 或 CBOR 等二进制编码比文本 JSON 编码更容易编码。然而 javascript 环境(如 v8/node.js)针对 JSON 处理进行了高度优化(因为它是 javascript 的子集)。 JSON de/encoding 可能直接在 JS VM 中以优化的方式在本机代码中实现。然而,javascript 虚拟机并未针对表示和操作字节数组(由 BSON 库使用)进行优化。节点原生 Buffer 类型可能比纯 JS 数组更好,但使用它(例如在 JS 中执行 JS 字符串 (UTF16) -> UTF8 字节解码)仍然比内置的 JSON 序列化慢。

在其他语言中,例如具有直接字节数组访问和 utf8 字符串类型的 C++,结果可能完全不同。