21个版本

使用旧的Rust 2015

0.7.3 2019年7月11日
0.7.1 2019年5月27日
0.7.0 2018年9月17日
0.5.0 2018年1月25日
0.3.0 2015年7月26日

#965 in 编码

Download history 5361/week @ 2024-03-14 5520/week @ 2024-03-21 5835/week @ 2024-03-28 6076/week @ 2024-04-04 5560/week @ 2024-04-11 5517/week @ 2024-04-18 4888/week @ 2024-04-25 4522/week @ 2024-05-02 5433/week @ 2024-05-09 5565/week @ 2024-05-16 4712/week @ 2024-05-23 5795/week @ 2024-05-30 5084/week @ 2024-06-06 4923/week @ 2024-06-13 4998/week @ 2024-06-20 4137/week @ 2024-06-27

20,143 每月下载量
用于 30 个crate (25 直接)

MIT 许可证

52KB
751

Abomonation

一个令人痛苦的Rust序列化库

Abomonation(拼写有意为之)是一个基于非常简单想法的Rust序列化库:如果有人提供了要序列化的数据,它将复制那些确切的位,然后跟随任何指针并复制那些位,依此类推。在反序列化时恢复确切的位,然后更正指针以指向所跟踪数据的序列化形式。

警告:Abomonation不应用于任何您非常关心的数据,或来自任何您重视数据的计算机。encodedecode 方法执行可能导致未定义行为的事情,您不应容忍这种行为。具体来说,encode 将填充字节暴露给 memcpy,而 decode 并不十分尊重对齐。

有关更多信息,请参阅abomonation文档

以下是一个使用Abomonation的示例。它非常容易使用。令人惊讶地容易。

extern crate abomonation;
use abomonation::{encode, decode};

// create some test data out of abomonation-approved types
let vector = (0..256u64).map(|i| (i, format!("{}", i))).collect();

// encode vector into a Vec<u8>
let mut bytes = Vec::new();
unsafe { encode(&vector, &mut bytes); }

// unsafely decode a &Vec<(u64, String)> from binary data (maybe your utf8 are lies!).
if let Some((result, remaining) = unsafe { decode::<Vec<(u64, String)>>(&mut bytes) } {
    assert!(result == &vector);
    assert!(remaining.len() == 0);
}

当您使用Abomonation时,事情可能会非常快。这是因为它所做的很少,主要是复制大量内存。键入

cargo bench

将触发Rust的基准测试基础设施(如果您不是使用nightly,则将发生错误。运气不好)。测试反复编码 Vec<u64>Vec<String>Vec<Vec<(u64, String)>>,得到如下数字:

test u64_enc        ... bench:         131 ns/iter (+/- 58) = 62717 MB/s
test string10_enc   ... bench:       8,784 ns/iter (+/- 2,791) = 3966 MB/s
test vec_u_s_enc    ... bench:       8,964 ns/iter (+/- 1,439) = 4886 MB/s

它们还反复解码相同的数据,得到如下数字:

test u64_dec        ... bench:           2 ns/iter (+/- 1) = 4108000 MB/s
test string10_dec   ... bench:       1,058 ns/iter (+/- 349) = 32930 MB/s
test vec_u_s_dec    ... bench:       1,232 ns/iter (+/- 223) = 35551 MB/s

这些吞吐量如此之高,因为要做的很少:内部指针需要更正,但在它们不存在的情况下(例如 u64),实际上没有任何事情要做。

请注意,这些数字并不是 goodput,而是移动的总字节数,等于数据的内存表示。在64位系统上,一个 String 需要24字节加上每个字符一个字节,对于小字符串来说可能会有很多开销。

不安全的_abomonate!

Abomonation宏通过 unsafe_abomonate! 实现为structs提供了 Abomonation,这些structs本质上等同于其他 Abomonable 类型元组的组合。要使用这个宏,必须在 #[macro_use] 修饰符之前放置 extern crate abomonation;

请注意,unsafe_abomonate! 自动生成 Abomonation 的不安全实现,因此调用它应被视为不安全的。

#[macro_use]
extern crate abomonation;
use abomonation::{encode, decode};

#[derive(Eq, PartialEq)]
struct MyStruct {
    pub a: String,
    pub b: u64,
    pub c: Vec<u8>,
}

// (type : field1, field2 .. )
unsafe_abomonate!(MyStruct : a, b, c);

// create some test data out of abomonation-approved types
let record = MyStruct{ a: "test".to_owned(), b: 0, c: vec![0, 1, 2] };

// encode vector into a Vec<u8>
let mut bytes = Vec::new();
unsafe { encode(&record, &mut bytes); }

// decode a &Vec<(u64, String)> from binary data
if let Some((result, remaining)) = unsafe { decode::<MyStruct>(&mut bytes) } {
    assert!(result == &record);
    assert!(remaining.len() == 0);
}

请注意,为类型实现 Abomonable 可能会导致巨大的灾难,并且完全不建议这样做。

无运行时依赖