#binary-encoding #binary #serialization #compile-time #macro

desse-derive

编译时大小已知的类型的高速二进制序列化和反序列化

4个版本

0.2.1 2019年4月23日
0.2.0 2019年4月23日
0.1.1 2019年4月4日
0.1.0 2019年4月2日

120#binary-encoding

Download history 161/week @ 2024-04-07 81/week @ 2024-04-14 110/week @ 2024-04-21 118/week @ 2024-04-28 180/week @ 2024-05-05 104/week @ 2024-05-12 63/week @ 2024-05-19 53/week @ 2024-05-26 110/week @ 2024-06-02 98/week @ 2024-06-09 116/week @ 2024-06-16 72/week @ 2024-06-23 39/week @ 2024-06-30 112/week @ 2024-07-07 60/week @ 2024-07-14 109/week @ 2024-07-21

每月下载量323次
用于 desse

MIT 许可证

23KB
373

Desse 构建状态

对于编译时大小恒定的类型(在编译时已知大小)提供超快二进制序列化和反序列化。这个crate不能用于序列化或反序列化动态分配的类型,如 StringVecHashMap 等,以及编译时大小未知的类型,如 &str 等。

二进制编码方案

这个crate使用一种最小的二进制编码方案,使得编码对象的尺寸将小于(在Rust添加对齐填充字节的情况下)或等于在运行中的Rust程序中的尺寸。例如,考虑以下 struct

struct MyStruct {
    a: u8,
    b: u16,
}

Desse::serialize 将将此结构体序列化为 [u8; 3],其中 3u8u16 大小的总和。

用法

desse 添加到 Cargo.tomldependencies 部分中。

[dependencies]
desse = "0.2"

Desse trait 可以使用 derive 宏为任何结构体或枚举(大小在编译时已知)实现。这个crate还提供了一个 derive 宏来实现 DesseSized trait,这对于实现 Desse trait 是必要的。

use desse::{Desse, DesseSized};

#[derive(Debug, PartialEq, Desse, DesseSized)]
struct MyStruct {
    a: u8,
    b: u16,
}

现在,您可以使用 Desse::serializeDesse::deserialize_from 来进行此结构的序列化和反序列化。

let my_struct = MyStruct { a: 5, b: 1005 };
let serialized: [u8; 3] = my_struct.serialize();
let new_struct = MyStruct::deserialize_from(&serialized);

assert_eq!(my_struct, new_struct);

请注意,Desse::serialize 返回一个固定长度的数组(在上面的例子中为 3),而 Desse::deserialize 将一个固定长度的数组的引用作为参数。

性能

此软件包更重视性能。如果使用经过测试和验证的 不安全 代码可以提升性能,我们不会回避使用。

基准测试

以下是 dessebincode 在序列化和反序列化相同的 struct 时的基准测试结果。

struct::serialize/desse::serialize
                        time:   [1.6228 ns 1.6326 ns 1.6434 ns]
                        change: [-1.1985% +0.0554% +1.2769%] (p = 0.94 > 0.05)
                        No change in performance detected.
Found 8 outliers among 100 measurements (8.00%)
  2 (2.00%) high mild
  6 (6.00%) high severe

struct::serialize/bincode::serialize
                        time:   [19.991 ns 20.081 ns 20.201 ns]
                        change: [-1.0739% +0.3569% +1.7361%] (p = 0.63 > 0.05)
                        No change in performance detected.
Found 12 outliers among 100 measurements (12.00%)
  3 (3.00%) high mild
  9 (9.00%) high severe

struct::deserialize/desse::deserialize
                        time:   [1.6063 ns 1.6101 ns 1.6144 ns]
                        change: [-1.3079% -0.1278% +1.0394%] (p = 0.84 > 0.05)
                        No change in performance detected.
Found 7 outliers among 100 measurements (7.00%)
  1 (1.00%) high mild
  6 (6.00%) high severe

struct::deserialize/bincode::deserialize
                        time:   [22.004 ns 22.094 ns 22.209 ns]
                        change: [-1.1573% +0.0698% +1.3631%] (p = 0.92 > 0.05)
                        No change in performance detected.
Found 9 outliers among 100 measurements (9.00%)
  3 (3.00%) high mild
  6 (6.00%) high severe

从上述基准测试中可以明显看出,bincode 的序列化平均需要 20.081 ns,而 desse 需要 1.6326 ns。反序列化时结果也类似,其中 bincode 需要 22.094 ns,而 desse 需要 1.6101 ns

您可以通过运行以下命令来运行基准测试:

cargo bench

未来改进

一旦 Rust 中的 const_generics 被实现,我们就可以为许多类型提供默认实现,例如,impl Desse for [T; n] where T: Desse,以及 Rust 中其他可变大小的静态分配类型。

许可

根据您的选择,许可如下:

等。

贡献

除非您明确声明,否则根据 Apache-2.0 许可证定义,您有意提交给作品包含的任何贡献,将按上述方式双许可,不附加任何额外条款或条件。

依赖项

~2MB
~46K SLoC