2个不稳定版本

0.1.0 2023年3月21日
0.0.1 2023年3月20日

#2309 in 编码

24每月下载量

MIT许可证

140KB
2K SLoC

ser_raw

ser_raw是一个简单且快速的序列化器。

请参阅doc.rs上的文档


lib.rs:

ser_raw

ser_raw是一个简单且快速的序列化器。

它使用Rust的本地内存布局作为序列化格式,因此序列化主要是简单地复制原始字节。这提供了两个主要优势

  1. 简单意味着它非常快。
  2. 反序列化可以是零拷贝和瞬时的 - 只需将指向序列化数据的指针强制转换为&T

此库的主要目标是用于同一台机器上不同进程之间(包括不同语言之间)的数据共享,但它也可以用于其他目的。

它有多快?

快!使用SWC(https://swc.rust-lang.net.cn/)生成的AST结构的大规模序列化基准测试

serde_json: 226.99 µs
rkyv:        44.98 µs
ser_raw:     14.35 µs

序列化器

此crate提供4种不同的序列化器,用于不同的用例。它们提供了一系列选项,在序列化期间或反序列化期间进行操作。它们主要区别在于它们处理指针的方式。

PureCopySerializer是最快且最简单的序列化器。不纠正指针,因此数据只能通过按顺序遍历值树来反序列化。

UnalignedSerializerPureCopySerializer相同,除了它不尝试正确对齐数据。

PtrOffsetSerializer用偏移量替换输入中的指针(例如,在BoxVecString中)。

这允许延迟反序列化,并允许反序列化器以任何顺序/方向遍历值树。

CompleteSerializer 将输入中的指针替换为指向输出的有效指针,并执行其他修正以确保输出是输入的完全有效表示。输入只需将输出缓冲区起始指针强制转换为 &T 即可“重新水化”。

自定义序列化器

此库提供了一个易于使用的 derive 宏,用于创建基于上述任意的自定义 Serializer

序列化器还可以选择不同的底层存储选项。此库提供了两个 - AlignedVecUnalignedVec - 或者你可以构建自己的 Storage 实现。

可序列化类型

目前只支持拥有和有大小类型的序列化。

包含对序列化常见 Rust 类型(例如 u8isizeNonZeroU32BoxVecStringOption)的支持,无需额外操作。

对于你自己的类型,实现 Serialize 特性。通常,你可以使用 derive 宏

use ser_raw::Serialize;

#[derive(Serialize)]
struct Foo {
	small: u8,
	vec: Vec<u32>
}

对于外部类型(即来自外部包的类型),使用 SerializeWith

反序列化

目前不提供反序列化器。

CompleteSerializer 不需要反序列化器,因为你可以直接将输出缓冲区指针强制转换为 &T

警告

由于序列化器只是直接复制 Rust 的内存,序列化器的输出将取决于它运行的系统(处理器架构、大端或小端、64 位或 32 位)。

Rust 也无法保证即使在同一系统上两次编译相同的代码,其内存布局也将相同(实际上通常是这样的,但你可以始终使用 #[repr(C)] 标记来确保)。

因此,应非常小心地确保反序列化发生在与序列化相同的机器上,并理想情况下使用相同的二进制文件。不匹配很可能导致内存不安全,并引发可怕的 未定义行为

For the primary use case for `ser_raw` - transfer of data within a single

系统 - 这些限制不是问题。

特性

derive 特性启用 Serialize derive 宏。默认启用。

未来方向和动机

创建这个库的主要动机是使Rust和JavaScript(通过napi-rs)之间能够快速共享数据。使用serde JSON的典型方法对于某些用例来说速度过于缓慢,而rkyv的实际速度也比预期慢。

想法是使用layout_inspect生成Rust类型布局的模式,并使用该模式生成匹配的JavaScript序列化器/反序列化器,该序列化器可以反序列化ser_raw的输出。

这正是为什么Rust中还没有实现反序列化的主要原因!我计划在JavaScript中执行反序列化。

致谢

ser_raw遵循与abomonation相同的序列化方法。它具有与abomonation相同的极快速度,同时旨在避免其安全问题(以及万圣节主题!)

rkyv也是灵感来源之一,而大多数ser_raw序列化器使用的后端存储AlignedVec基于rkyv的同名类型。

traits用于创建序列化器。由Serializer derive宏内部使用。

依赖项

~1.5MB
~35K SLoC