毫斯克包装器
Msgpacker包是一个极快的MessagePack NodeJS/JavaScript执行. 目前,执行速度大大快于任何其他已知执行速度,快于Avro(JS),一般快于NodeJS上的原生V8 JSON.stringify/parse. 它还包括一个可选的记录扩展(即: r 在msgpackr)中,用于定义使MessagePack更快更紧凑的记录结构,往往比本地JSON功能快一倍多,比其他JS执行速度快多出多出多出多出多出多出多出多出多出多出多出多出多出多出多出多出多出少出多出多出多出少出多出多出多出多出多出多出多出多出少出多出少出少出少出多出多出少出多出多出多出多出多出少出少出多出少出多出少出多出少出多出少出多出少出少出多出少出多出多出少出多出多出多出少出多出多出多出多出多出少出少出少出多出少出少出多出少出多出多出多出多出少出多出多出多出多出多出多出多出多出多出少出多出多出多出多出多出多出多出多出多出多出多出多出多出 详情见业绩部分。 结构化克隆(有周期性参考支持)也通过可选扩展支持.
基本用途
安装方式 :
npm i msgpackr
还有 import 或者说 require 用于基本标准序列化/编码(pack)和去序/解码(unpack职能:
import { unpack, pack } from 'msgpackr';
let serializedAsBuffer = pack(value);
let data = unpack(serializedAsBuffer);
这个 pack 函数将生成标准MessagePack,而无需任何与任何标准MessagePack解析器/解码器相兼容的扩展. 它将把 JavaScript 对象序列化为信件包 maps 默认。 这个 unpack 函数将把信件包去序列化 maps 作为 Object 和地图上的属性.
节点使用
Msgpacker软件包运行于任何现代JS平台上,但被优化为NodeJS用法(并将使用节点附加来进行性能助推作为可选的依赖).
流线
我们可以使用包含的流线功能(这进一步提高了性能). 这个 PackrStream 是可用于将对象序列化为二进制流的节点JS变换流(写入到网络/socket, IPC等),以及 UnpackrStream 可用于从二进制 sream(从网络/socket等读取)中去除对象:
import { PackrStream } from 'msgpackr';
let stream = new PackrStream();
stream.write(myData);
或在流中发送和接收数据的完整例子:
import { PackrStream, UnpackrStream } from 'msgpackr';
let sendingStream = new PackrStream();
let receivingStream = new UnpackrStream();
// we are just piping to our own stream, but normally you would send and
// receive over some type of inter-process or network connection.
sendingStream.pipe(receivingStream);
sendingStream.write(myData);
receivingStream.on('data', (data) => {
// received data
});
这个 PackrStream 财务报告和审定财务报表 UnpackrStream 实例还将默认启用记录结构扩展(见下文).
德诺和邦用法
Msgpacker模块是标准的无害环境管理模块,可直接从 msgpacker的地籍登记 或使用国家防范机制模块加载器 import { unpack } from 'npm:msgpackr'. 标准包/编码和可拆装/解码功能与其他平台一样,在德诺上可提供. msgpacker可以和邦上的其他任何软件包一样被使用.
浏览器使用
Msgpacker也作为独立的JavaScript工作,在现代浏览器上运行. 它包括一个捆绑的脚本,在 dist/index.js 为方便直接装载:
<script src="node_modules/msgpackr/dist/index.js"></script>
这是基于UMD的,如果可能的话,将登记为模块,或创建 msgpackr 带有所有导出函数的 global.
对于基于模块的开发,建议您直接导入感兴趣的模块,以尽量减少被拉入您的应用程序的依赖性:
import { unpack } from 'msgpackr/unpack' // if you only need to unpack
该套装还包括了index.min.js中精密的捆绑. 此外,该套件还包括一个版本,不包括动态代码评价,称为index-no-eval.js,针对内容安全政策(CSP)在代码中禁止eval/功能的情况. 动态评价提供了重要的性能优化(用于记录),因此除非CSP政策要求,否则不推荐.
结构化克隆
您也可以使用 msgpacker 来进行 结构克隆通过使 structuredClone 选项,可以包括其它对象的引用或循环引用,对象身份将被保留。 结构克隆还能够保护某些打字对象,例如: Error, (中文(简体) ), Set, (中文(简体) ), RegExp 和键入箭头实例。 例如:
let obj = {
set: new Set(['a', 'b']),
regular: /a\spattern/
};
obj.self = obj;
let packr = new Packr({ structuredClone: true });
let serialized = packr.pack(obj);
let copy = packr.unpack(serialized);
copy.self === copy // true
copy.set.has('a') // true
此选项默认被禁用, 因为它使用扩展和引用检查可降解性能( 约 25- 30%) 。 (注意此执行不会序列化HTML规格中指定的每个类别/类型,因为并非所有类别/类型都适合跨平台存储)
备选术语
如果您喜欢使用编码/解码术语, msgpacker 输出别名, 所以 decode 等同为 unpack, (中文(简体) ), encode 实值 pack, (中文(简体) ), Encoder 实值 Packr, (中文(简体) ), Decoder 实值 Unpackr,以及 EncoderStream 财务报告和审定财务报表 DecoderStream 也可以用来.
记录/ 对象结构
持有任意一组密钥和值的地图(或词典)之间有关键区别(JavaScript) Map ),以及具有一套定义明确的字段的记录或对象结构。 典型的JS对象/记录可能有许多重复(使用)同一结构的情况. 通过使用记录扩展,这种区分在MessagePack中被保留,编码可以再用结构,不仅提供更好的类型保存,而且产生出更紧凑的编码并增加2-3x的解码性能. Msgpacker 自动生成被重用并被结构相同的对象引用的记录定义. 利用这一点对我们有利有多种方式。 对于具有类似结构的重复嵌入对象的大型物体结构,只要与记录扩展相串接就可以产生显著的好处. 为了使用记录结构扩展,我们创建一个新的 Packr 举个例子 默认新建 Packr 实例将启用记录扩展 :
import { Packr } from 'msgpackr';
let packr = new Packr();
packr.pack(bigDataWithLotsOfObjects);
进一步利用msgpacker记录结构好处的另一种方式是使用流来自然允许数据基于先前的记录结构再利用. 溪流类有默认允许的记录结构扩展功能,并提供出色的出箱性能.
创建新时 Packr, (中文(简体) ), Unpackr, (中文(简体) ), PackrStream,或 UnpackrStream 实例中,我们可以启用或禁用带有 useRecords 属性。 当这是 false,则将禁用记录结构扩展(标准/兼容模式),所有对象将恢复使用MessageMap进行序列化 maps,还有所有 maps将脱离联署机构 Objects 如属性( 如独立 pack 财务报告和审定财务报表 unpack 函数).
与记录结构相接,通过首次在流中看到一个结构时将其编码,并在通过流中发送的后期信件中引用结构。 当一个编码器可以期望一个解码器能够理解先前的结构引用时,可以使用 sequential: true 旗,由溪流自动启用,但也可用于Packer实例.
共享记录结构
使用msgpacker和记录扩展的另一种有用的方法是将数据存储在数据库,文件或其他存储系统中. 如果正在存储一些具有共同数据结构的对象,可以使用共享结构来大大提高数据存储和去序列化效率. 以最简单的形式提供 structures 数组,如果遇到新的对象结构,则更新:
import { Packr } from 'msgpackr';
let packr = new Packr({
structures: [... structures that were last generated ...]
});
如果你正在使用持续的数据,你将需要坚持 structures 更新时的数据。 Msgpacker 提供了用于加载和保存的 API structures 根据需要(很强壮,可用于其他进程可能也在更新的多进程情况) structures 我们只需要提供一种方法来存储生成的共享结构 这样它就可以在将来将存储的数据去序列化:
import { Packr } from 'msgpackr';
let packr = new Packr({
getStructures() {
// storing our data in file (but we could also store in a db or key-value store)
return unpack(readFileSync('my-shared-structures.mp')) || [];
},
saveStructures(structures) {
writeFileSync('my-shared-structures.mp', pack(structures));
}
});
Msgpacker会在遇到任何新的对象结构时自动添加并保存结构(默认的上限为32). 它将始终以递增/兼容的方式增加结构: 任何用更早的结构编码的对象都可以用后发版本来解码(只要坚持).
共享结构选项
默认有32个共享结构的限制。 这种默认是为了记录常见的共享结构,但如果存在许多具有活性特性的物体有可能被重复,也能够抵御共享过多的结构. 这也允许稍微提高一个字节编码的效率. 但是,如果应用程序具有更多常见重复的结构,您可以通过设置来增加此限制 maxSharedStructures 到更高的价值。 最大支持共享结构为8160.
您也可提供 shouldShareStructure 函数,如果您想具体指明哪些结构应当共享。 这在编码过程中被调用,其中包含一个正在考虑添加共享结构的结构的密钥数组. 例如,你可能想要:
maxSharedStructures: 100,
shouldShareStructure(keys) {
return !(keys[0] > 1) // don't share structures that consist of numbers as keys
}
读取多值
如果有一个缓冲器,并按顺序编码多个值,可以选择解析并读取多个值. 使用 unpackMultiple 函数/方法,该函数/方法可以返回它可以依序在提供的缓冲内分析的所有值的数组。 例如:
let data = new Uint8Array([1, 2, 3]) // encodings of values 1, 2, and 3
let values = unpackMultiple(data) // [1, 2, 3]
反之,您可以提供一个调用函数,在解析每个值时称为调用函数,也可以通过返回来选择终止解析 false数字 :
let data = new Uint8Array([1, 2, 3]) // encodings of values 1, 2, and 3
unpackMultiple(data, (value) => {
// called for each value
// return false if you wish to end the parsing
})
如果您需要了解已解开的数值的起始和结尾偏移,这些是 作为回调中的可选参数提供:
let data = new Uint8Array([1, 2, 3]) // encodings of values 1, 2, and 3
unpackMultiple(data, (value,start,end) => {
// called for each value
// `start` is the data buffer offset where the value was read from
// `end` is `start` plus the byte length of the encoded value
// return false if you wish to end the parsing
})
选项
下列选项属性可以提供给Packer或Unpacker构造器:
useRecords- 设为false禁用记录扩展并存储 JavaScript 对象为 MessagePack 地图, 并解包地图为 JavaScriptObjects,确保与其他解码器相容. 设置此函数将使用记录来记录对象useRecords(object)返回时true。 。 。 .structures- 提供用于记录扩展的架构阵列,如果需要保存和使用。 这个阵列将随着新记录结构被序列化(如果阵列中少于32个结构)而进行修改.moreTypes- 允许其他内置类型/类的序列化,包括打入的阵列,Sets, (中文(简体) ),Maps,和Error编号.structuredClone- 使结构化克隆扩展能够编码对象/循环参考.moreTypes当启用时默认启用.mapsAsObjects- 狦true,这将解码 MessagePack地图和JSObjects 已解码为对象属性的地图条目。 若为false,将地图解码为 JavaScriptMaps. (中文(简体) ). 如果useRecords启用( 允许Maps 要保存),并在默认情况下启用,如果useRecords已禁用.useFloat32- 这将使msgpacker能够将非整数编码为float32。关于可能的数值,见下一节.variableMapSize- 这将使用不同的地图大小定义(fixmap, map16, map32),基于编码对象时的密钥数量,这些密钥产生略多的紧凑编码(对于小对象),但在编码过程中通常会慢出5-10%. 如果需要使用超过65535个密钥的对象,则需要使用此功能. 仅在记录扩展被禁用时才与此相关 .bundleStrings- 狦true它使用自定义扩展将字符串捆绑在一起,这样它们就可以被更快地解码到浏览器和无法访问节点JS addon的Deno上. 这个自定义扩展,所以编码器和解码器都需要支持. 这可以在浏览器上产生显著的解码性能提升(30%-50%).copyBuffers- 当用二进制数据(Buffers被编码为二进制数据)解码邮件包时,复制缓冲器,而不是提供缓冲器的切片/视图. 如果您想要在解码后嵌入缓冲器继续运行的同时收集或修改您的输入数据,您可以使用此选项(有额外的间接费用来复制).useTimestamp32- 编码JSDates 在可能情况下通过降低毫秒格式。 这是更有效的日期编码。 您也可以通过手动设置毫秒为0来导致日期使用32位格式(date.setMilliseconds(0)) (中文(简体) ).sequential- 序列化数据中的编码结构,并参照以前编码的结构,期望解码器按编码的顺序阅读编码结构unpackMultiple。 。 。 .largeBigIntToFloat- 如果需要将大于64位整数的比奇特编码为浮-64(否则会扔出RangeError).largeBigIntToString- 如果需要将比64位整数中更大的比奇特编码成字符串(否则会扔出RangeError).useBigIntExtension- 如果需要将比64位整数中的比特编码更大,则将使用一个自定义扩展来编码,该扩展支持最多可达1000位整数精度.encodeUndefinedAsNil- 编码一个值:undefined作为信件包nil,与null。 。 。 .int64AsType- 这将解码为指定的类型。 类型可以是bigint(违约),number, (中文(简体) ),string,或auto(其中范围[-2^53...2^53]由数字来表示,其他一切则由比特表示).skipValues- 这可以是一系列属性值,以表示在序列化对象时应当跳过的属性。 例如,模仿JSON.stringify跳过属性且其值为undefined,您可以提供skipValues: [undefined]。注意,这仅适用于作为标准MessagePack地图的序列化对象,而不适用于记录。 此外,通过调用include方法,因此您可以提供对象includes如果您想要自定义函数跳过值.onInvalidDate- 这可以作为在提供无效日期时调用的函数提供。 该函数可以抛出一个错误,或者返回一个将被编码的值来代替无效的日期. 如果不提供, 无效的日期将被编码为无效的时间戳( 用 msgpacker 解码为无效的日期) .writeFunction- 可以在遇到一个函数时作为调用函数提供。 该函数可以抛出出一个错误,或者返回一个将被编码的值来取代该函数. 如果不提供,函数将被编码为未定义(类似于JSON.stringify) (中文(简体) ).mapAsEmptyObject- 联合来文编码Maps 作为空对象(用于与旧库的后比).setAsEmptyObject- 联合来文编码Sets 作为空对象(用于与旧库的后比).allowArraysInMapKeys- 允许在地图中将数组用作按键,只要所有元素是字符串、数字、布林斯或大意。 当启用时,此类阵列被平整并转换为字符串表示.
32 位浮点选项
默认情况下,所有非整数被序列化为64位浮点数(double). 这是快速的,并确保最大精确。 然而,通常现实世界的数据并不需要64位精度,而使用32位编码可以更高效地使用空间. 有几个选项可以提供更有效的编码. 使用十进制的四舍五入选项来进行编码和解码,以更高效的32位格式(而不是64位),提供像7.99这样的普通十进制表示的无损失存储. 这个 useFloat32 属性有几种可能的选项,从模块中可作为常数:
import { FLOAT32_OPTIONS } from 'msgpackr';
const { ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
ALWAYS(1) - 总是会将非嵌入(绝对小于2147483648)编码为32位浮点.DECIMAL_ROUND(3)- 总是会将非嵌入式编码为32位浮点,当解码为32位浮点时,会圆到显著的小数位数(通常为7位,但某些范围为6或8位).DECIMAL_FIT(4) - 如果所有显著的位数(通常可高达7个)都能被毫不含糊地编码为32位浮点,并用小数四舍五入来解码/解码/解码包(与上同),则只有将非入位符编码为32位浮点. 这将确保圆通编码/解码不丧失精度,并在可能时使用32位.
注意, 性能随着小数四舍五入而减少约 20- 25%, 尽管如果您的值只有 5% 是浮动点, 总体影响将只有 1% .
此外,msgpacker出口a roundFloat32(number) 函数,可以用来将浮点数圆为可被存储在32位浮点数中的最大重要小数位数,就像DECIMAL ROUND在解码时所做的那样。 这可用于确定一个数字在编码之前如何被解码.
业绩
本土加速
Msgpacker 使用可选的本地节点-addon来加速字符串解析. 应在节点JS上自动安装和使用。 不过,你可以通过检查 isNativeAccelerationEnabled 从 msgpacker 导出属性。 如果这是 false,则 msgpackr-extract 软件包可能没有正确安装,您可能想要验证其安装正确:
import { isNativeAccelerationEnabled } from 'msgpackr'
if (!isNativeAccelerationEnabled)
console.warn('Native acceleration not enabled, verify that install finished properly')
基准
Msgpacker是快速的。 痷е 以下是使用基准工具与下一个最快的联署项目进行对比: msgpack-lite (而且样本数据来自我们使用的一些临床研究数据,这些数据有着不同价值类型和结构的良好组合). 它还包括比较V8本土JSON功能,和JavaScript Avro(avsc,一个非常优化的 Avro 执行:
| 操作 | 执行 | 分钟 | 行动 |
|---|---|---|---|
| buf = Buffer(JSON.stringify(obj)); | 81600 (简体中文) | 5002 (中文(简体) ) | 16313 (英语) |
| obj = JSON.parse(buf); | 90700 (英语) | 5004 (英语) | 18125 (英语) |
| a. 需要(“msgpacker”); | 169700 (英语) | 5000块 | 33940 (英语) |
| 需要( “ msgpacker ”). unpack( buf ); | 109700 (英语) | 5003 (英语) | 21926 (英语) |
| msgpackr w/ 共享结构: packer.pack(obj); | 190400 (英语) | 5001 (简体中文) | 38072 (英语) |
| msgpackr w/ 共享结构: packr.unpack (buf); | 422900 (英语) | 5000块 | 84580 (英语) |
| buf = 需要 ("msgpack-lite"). encode(obj;); | 31300号 | 5005 (英语) | 6253号 |
| obj = 要求 ("msgpack-lite").decode (buf;); | 15700 (英语) | 5007 (中文(简体) ) | 3135号 |
| buf = 要求 ("@msgpack/msgpack"). encode (obj) ; | 103100 (英语) | 5003 (英语) | 20607 (韩语) |
| obj = 要求 ("@msgpack/msgpack"). decode (buf) ; | 59100 (韩语) | 5004 (英语) | 11810 (中文(简体) ) |
| buf = 需要 ("注包"). encode(obj; ; ); | 65500 (英语) | 5007 (中文(简体) ) | 13081 (英语) |
| obj = 要求 ("注包").decode (buf); | 33400号 | 5009 (英语) | 6667 (英语) |
| obj = 需要 ("msgpack- unpack").decode (buf) ; | 6900号 | 第5036条 | 1370号 |
| 需要( “ avsc ” )... make schema/ type. to Buffer( obj ) ; | 89300号 | 5005 (英语) | 17842 (英语) |
| 需要( “avsc ” )... make schema/ type. type. from Buffer( obj ) ; | 108400 (英语) | 5001 (简体中文) | 21675 (英语) |
所有基准都是在15号/V8 8.6号(Windows i7-4770 3.4Ghz)上实现的.
(单位:千美元)avsc 以图案为基础,在风格上与有共享结构的msgpacker比较.
以下是流数据的基准(再次借用自 msgpack-lite,其中msgpacker能够利用结构化的记录扩展并真正展示其性能能力:
| 操作 (1000000 x 2) | 执行 | 分钟 | 行动 |
|---|---|---|---|
| 新建 PackerStream ().write(obj); | 1 000 000 个 | 372个 | 2688172 (中文(简体) ) |
| 新的UnpackrStream (. write (buf) ); 新软件; | 1 000 000 个 | 247 (中文(简体) ) | 4048582 (英语) |
| shreet.write(msgpack.encode(obj)) ; 页面存档备份,存于互联网档案馆; | 1 000 000 个 | 2898 (英语) | 345065 (英语) |
| stream.write(msgpack.decode (buf)) (英语); | 1 000 000 个 | 1969年 纽约 | 507872 (英语) |
| stream.write(notepack.encode(obj)) ; 页面存档备份,存于互联网档案馆; | 1 000 000 个 | 901 (简体中文) | 1109877 (英语) |
| sream.write(notepack.decode(buf)); ); | 1 000 000 个 | 第1012号 | 988142 (中文(简体) ) |
| msgpack. Encoder ().on ("data",ondata).encode (obj); (中文(简体) ); | 1 000 000 个 | 1763 (英语) | 第567214号 |
| msgpack.create-Decode-Stream (.write(buf)); (中文(简体) ); | 1 000 000 个 | 2222 (英语) | 450045 (英语) |
| msgpack.create EncodeStream (. write (obj) ; 页面存档备份,存于互联网档案馆; | 1 000 000 个 | 第1577号 | 页:1 |
| msgpack.Decoder ().on ("data",ondata).decode (buf;); | 1 000 000 个 | 第2246号 | 445235 (英语) |
见 基准数据d 需要更多的基准和关于基准的信息.
自定义扩展名
您可以添加自定义扩展名, 该扩展名可用于以某些方式编码特定类型/类 。 这是通过使用 addExtension 函数,并指定类,扩展名 type 代码(应为1-100的号码,为MessagePack保留负数,为msgpackr保留101-127),以及您 pack 财务报告和审定财务报表 unpack 函数.
import { addExtension, Packr } from 'msgpackr';
class MyCustomClass {...}
let extPackr = new Packr();
addExtension({
Class: MyCustomClass,
type: 11, // register your own extension code (a type code from 1-100)
pack(instance) {
// define how your custom class should be encoded
return Buffer.from([instance.myData]); // return a buffer
},
unpack(buffer) {
// define how your custom class should be decoded
let instance = new MyCustomClass();
instance.myData = buffer[0];
return instance; // decoded value from buffer
}
});
如果您想要使用 msgpacker 来编码和解码您的扩展内的数据, 您可以使用 read 财务报告和审定财务报表 write 函数以及读取和写入由msgpacker编码并解码的数据/对象,比创建和接收单独的缓冲器容易和快:
import { addExtension, Packr } from 'msgpackr';
class MyCustomClass {...}
let extPackr = new Packr();
addExtension({
Class: MyCustomClass,
type: 11, // register your own extension code (a type code from 1-100)
write(instance) {
// define how your custom class should be encoded
return instance.myData; // return some data to be encoded
}
read(data) {
// define how your custom class should be decoded,
// data will already be unpacked/decoded
let instance = new MyCustomClass();
instance.myData = data;
return instance; // return decoded value
}
});
注意,您可以从 write,在这种情况下,msgpacker将使用默认对象/阵列编码编码它:
addExtension({
Class: MyCustomClass,
type: 12,
read: function(data) {
Object.setPrototypeOf(data, MyCustomClass.prototype)
return data
},
write: function(data) {
return data
}
})
您也可以创建扩展名 Class 财务报告和审定财务报表 write 方法,但没有 type (或 read),如果您只是想自定义一个类的序列,而不使用MessagePack扩展编码.
其他性能优化
Msgpacker已经快了, 但这里有一些小费 使它更快:
缓冲重用
Msgpacker的设计效果与可再使用的缓冲器相适应. 分配出新的缓冲器可能比较昂贵,所以如果有节点加通,那么再利用缓冲器和用memcpy来将数据复制到现有的缓冲器中可以更快得多. 然后是Msg包装工 unpack 可以在同一个缓冲器上执行,有新的数据,并且可选择地取出第二个参数,表示缓冲器中可用数据的有效大小.
竞技场分配useBuffer()(中文(简体) )
在序列化过程中,数据被写入缓冲. 同样,分配新的缓冲器是一个相对昂贵的过程 useBuffer 方法可以帮助允许再利用能进一步提高性能的缓冲. 与 useBuffer 方法,可以提供缓冲器,将数据串入其中,当知道使用缓冲器完成时,可以调用 useBuffer 重新使用它。 使用 useBuffer 缓冲器即使不使用也会通过GC处理和清理,它只是提供少量的性能提升.
记录结构扩展定义
记录构造扩展使用扩展 id 0x72 ("r") 来宣告此功能的使用. 扩展名"data"字节(或字节)表示用于在之后的MessagePack块或流中识别一个记录开始的字节或字节. 标识符字节(或一个序列中的第一个字节)必须是从0x40 - 0x7f(并因此取代正整数64 - 127的一个字节表示法,它可以由int或int类型相交表示). 扩展声明必须随即由定义记录结构的字段名的MessagePack数组来进行.
一旦对记录标识符和记录字段名称进行了定义,解码器/解码器就应该读取下一个值。 随后在块或流中将记录标识符作为值的任何使用,都应被解析为记录实例,下一个n值,其中n为字段数(由字段名数组所定义),应当被读取为字段值. 例如,我们在这里定义了一个带有"foo"和"bar"字段的结构,其记录标识符为0x40,然后读取一个分别定义了4和2字段值的记录实例:
+--------+--------+--------+~~~~~~~~~~~~~~~~~~~~~~~~~+--------+--------+
| 0xd4 | 0x72 | 0x40 | array: [ "foo", "bar" ] | 0x04 | 0x02 |
+--------+--------+--------+~~~~~~~~~~~~~~~~~~~~~~~~~+--------+--------+
生成一个对应 JSON 的对象:
{ "foo": 4, "bar": 2}
附加价值类型
毫斯克包装器支持 undefined (使用fixext1+类型:0+数据:0来配合其他JS执行),, NaN, (中文(简体) ), Infinity,以及 -Infinity (使用标准 IEEE 754 表示有双相/浮相).
日期
msgpacker 保存全部 JavaScript Dates 使用标准MessagePack日期扩展(type -1),使用存储日期而无需丢失数据所需的最小的32位,64位或96位格式(或者在指定使用Timestamp32选项时使用32位).
结构化克隆
随着结构化克隆的启用,msgpacker还将使用扩展存储Set, Map, Error, RegExp, ArrayBufferView 对象并保存其类型.
备用编码/包件
MSGPacker软件包中的高性能序列化和去序列化算法也存在于其中 cbor-x (英语) 用于CBOR格式,具有相同的API和设计. 使用MessagePack vs CBOR的利弊简略为:
- MessagePack的采用范围更广,而且至少随着这一执行,效率略高(约1%).
- CBOR有一个 正式的 IETF 标准化轨道,而记录扩展在概念/哲学上更适合CBOR标签.
许可证
麻省理工学院
浏览器考虑
MessagePack可以成为高性能数据传送给浏览器的一大选择,因为不压缩就可能实现合理的数据大小. 而msgpacker在现代浏览器中效果非常好. 然而,值得注意的是,如果想要高度紧凑的数据,brotli或gzip在压缩中最为有效,而MessagePack的字符频率往往会击败这些标准压缩算法使用的Huffman编码,导致压缩后的数据比JSON更紧凑.
贷项
各种项目为此提供了灵感,并借用了代码 https://github.com/msgpack/msgpack-javascript 财务报告和审定财务报表 https://github.com/mtth/avsc (中文(简体) )。 。 。 .