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 编码
20,143 每月下载量
用于 30 个crate (25 直接)
52KB
751 行
Abomonation
一个令人痛苦的Rust序列化库
Abomonation(拼写有意为之)是一个基于非常简单想法的Rust序列化库:如果有人提供了要序列化的数据,它将复制那些确切的位,然后跟随任何指针并复制那些位,依此类推。在反序列化时恢复确切的位,然后更正指针以指向所跟踪数据的序列化形式。
警告:Abomonation不应用于任何您非常关心的数据,或来自任何您重视数据的计算机。encode
和 decode
方法执行可能导致未定义行为的事情,您不应容忍这种行为。具体来说,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
可能会导致巨大的灾难,并且完全不建议这样做。