Zero-copy vector abstractions over byte arrays.
zerovec
enable vectors of multibyte types to be backed by a byte array, abstracting away
issues including memory alignment and endianness.
This crate has two main types:
ZeroVec<T>
for fixed-width types like u32
VarZeroVec<T>
for variable-width types like str
Both are intended as drop-in replacements for Vec<T>
in Serde structs serialized with a
format supporting a borrowed byte buffer, like Bincode. Clients upgrading from Vec to ZeroVec
or VarZeroVec benefit from zero heap allocations when deserializing read-only data.
zerovec
is designed for fast deserialization from byte buffers with zero memory allocations
while minimizing performance regressions for common vector operations.
Benchmark results on x86_64:
| Operation | Vec<T>
| zerovec
|
|---|---|---|
| Deserialize vec of 100 u32
| 233.18 ns | 14.120 ns |
| Compute sum of vec of 100 u32
(read every element) | 8.7472 ns | 10.775 ns |
| Binary search vec of 1000 u32
50 times | 442.80 ns | 472.51 ns |
| Deserialize vec of 100 strings | 7.3740 us* | 1.4495 us |
| Count chars in vec of 100 strings (read every element) | 747.50 ns | 955.28 ns |
| Binary search vec of 500 strings 10 times | 466.09 ns | 790.33 ns |
* This result is reported for Vec<String>
. However, Serde also supports deserializing to Vec<&str>
; this gives 1.8420 us, much faster than Vec<String>
but a bit slower than zerovec
.
The benches used to generate the above table can be found in the benches
directory in the project repository.
serde
: enables Serde Serialize/Deserialize impls for ZeroVec and VarZeroVec.Serialize and deserialize a struct with ZeroVec and VarZeroVec with Bincode:
```rust use zerovec::{ZeroVec, VarZeroVec};
// This example requires the "serde" feature
pub struct DataStruct<'s> { #[serde(borrow)] nums: ZeroVec<'s, u32>, #[serde(borrow)] strs: VarZeroVec<'s, String>, }
let data = DataStruct { nums: ZeroVec::fromaligned(&[211, 281, 421, 461]), strs: VarZeroVec::from(vec!["hello".tostring(), "world".tostring()]), }; let bincodebytes = bincode::serialize(&data) .expect("Serialization should be successful"); asserteq!(54, bincodebytes.len());
let deserialized: DataStruct = bincode::deserialize(&bincodebytes) .expect("Deserialization should be successful"); asserteq!(Some(211), deserialized.nums.first()); asserteq!(Some("world"), deserialized.strs.get(1)); assert!(matches!(deserialized.nums, ZeroVec::Borrowed())); ```
For more information on development, authorship, contributing etc. please visit ICU4X home page
.