[博客翻译]不愿选择CBOR而不是MessagePack


原文地址:https://taylor.town/flat-scraps-001


不情愿地选择CBOR而非MessagePack

在我追求一个可分享的编程语言的过程中,我需要一种合适的序列化格式,这种格式必须(1)高效用于发送和存储,以及(2)易于理解和实现。

被序列化的Scrapscript表达式被称为“flat scraps”。在之前的一篇文章中,我将Scrapscript塞进了MessagePack里。当时,我还不知道Max Bernstein已经写了一个大约100行代码的完整序列化器。这让我大吃一惊!

经过进一步的实验,我逐渐说服自己,这种序列化格式还需要做到:(3)遵守现有标准,(4)能兼任伪中间表示(IR),并且(5)能在相对较差的硬件上运行。

我仍处于探索阶段。即使看到了流行的CBOR和MessagePack实现的复杂性,Max的格式仍然非常有吸引力。与此同时,Peter Saxton给我发了一封友好的电子邮件,推荐了CBOR作为MessagePack的潜在替代方案。

呃哦——竞争标准?设计上的细微权衡?开源问题?系好安全带吧!

戏剧性虽然有趣,但与本文无关。这篇文章很好地总结了CBOR的历史。这条评论则链接到最激烈的公开争执。

哪个更酷?

显然,MessagePack是那些所谓“酷孩子”会用的东西。
比较每个主页的小标题:

  • MessagePack: “它就像JSON,但快且小。”
  • CBOR: “RFC 8949 简洁二进制对象表示”

其中一个格式竟然还戴着领带!关于CBOR的一切都不酷。它是委员会设计的。散发着RFC的气息。首字母缩写词很无趣。说“SEE-BORE”就像是舔镍币一样。其中一位作者是“Carsten Bormann”,这让这个名字听起来有点自娱自乐。

CBOR受到了MessagePack的启发。MessagePack由Sadayuki Furuhashi("frsyuki")开发和推广。
-- RFC 8949

忠于“原始”品牌是有价值的。与其追逐微小的改进,不如支持那些从几乎一无所有中创造价值的创造者。选择衍生作品可能让人感觉像是选择了官僚主义而不是个人表达。

哪个更高效?

然而很多人并不关心“酷”,他们想要的是压缩、速度和性能。

在这项基准测试中,作者比较了两个流行Go库的性能。从这些测试来看,CBOR库似乎编码/解码速度快约200%。

条形图展示了编码基本数据类型所需的时间 - nil, int64, uint64, bool, bytes, string, array 和 map。此基准测试是在Go语言中使用msgpack包和gson包完成的。源代码在这里、这里和这里提供。

哪个更简单?

但效率不是全部。我通常会选择概念上的简单性胜过性能。像大多数创造者一样,我不喜欢依赖于无法理解的力量。

要衡量复杂性,通常可以用文档长度作为一个代理。MessagePack只是一个markdown文件。而CBOR规范则有自己的引力场。

然而,经过进一步审查,我发现文档嗅探测试误导了我。这个HN评论分享了我的最新想法:

是的,我跳过了所有的戏剧性,阅读了规范并实现了编码器/解码器。CBOR就是这样应该从一开始就该做的MessagePack-like格式:它技术上更加优越,因为它是整洁和简单的,用一种概括取代了许多专门的规则。

在顶层,MessagePack定义了许多类型:整数、浮点数、数组、扩展等。CBOR通过“标签”统一了这些类型;这种模式似乎更容易解释和实现。

这个人认为CBOR的标签设计得不好。尽管我尊重地不同意他的结论,但我认为他提出了一些很好的观点。

哪个更流行?

“序列化”常常与“通信”相关联。带宽是昂贵的,所以像MessagePack和CBOR这样的格式自然成为计算机协议的候选者。

梅特卡夫定律指出,协议的价值与其流行度成正比。

数据本身说明了一切:

3.1K☆ C msgpack/msgpack-c
2.4K☆ Go vmihailenco/msgpack
1.9K☆ Python msgpack/msgpack-python
1.8K☆ Go tinylib/msgp
1.4K☆ Java msgpack/msgpack-java
1.4K☆ JS msgpack/msgpack-javascript
1.2K☆ Rust# 3Hren/msgpack-rust
1.0K☆ JS kawanet/msgpack-lite
837☆ C# msgpack/msgpack-cli
806☆ Go fxamacker/cbor
784☆ PHP msgpack/msgpack-php
764☆ Ruby msgpack/msgpack-ruby
529☆ JS kriszyp/msgpackr
519☆ C intel/tinycbor
364☆ JS hildjj/node-cbor
354☆ C PJK/libcbor
320☆ JS paroga/cbor-js
311☆ JS msgpack/msgpack-node
303☆ JS kriszyp/cbor-x
300☆ Rust pyfisch/cbor
284☆ Rust enarx/ciborium
243☆ Python agronholm/cbor2
214☆ C# peteroupc/CBOR
210☆ Erlang msgpack/msgpack-erlang
196☆ Haskell well-typed/cborg
142☆ Swift valpackett/SwiftCBOR
138☆ Haskell msgpack/msgpack-haskell
119☆ Java c-rack/cbor-java

对于我的特定用途来说,CBOR完全胜出。我更喜欢CBOR,但我讨厌自己更喜欢CBOR的事实。使用带有政治包袱的技术让我有些困扰。

不管怎样,MessagePack和CBOR相比JSON都是巨大的进步。只要MessagePack保持其流行优势,两种选择似乎都合理。

协议很重要。谨慎沟通。