stackvec-rs (version 0.0.2)
A rust crate to use stack-allocated vectors (to improve performance and/or when there is no std)
⚠️⚠️ Warning: unsafe is used ⚠️⚠️
And hasn't been thoroughly tested yet. It is thus ill-suited for production. Use at your own risk.
Since stackvec-rs provides very similar functionality to the more mature arrayvec, you should use that crate until stackvec-rs is mature enough (version 0.1.0 or even 1.0.0)
Motivation
Rust stack/inline arrays don't implement 2 very useful iterator-related interfaces:
-
IntoIterator<Item = T> for [T; n]- Allows using
.into_iter()instead of.iter().cloned()(which, by the way, can only be used whenT: Clone, and requires cloning, which may be expensive) -
let array: = ; let set: HashSet = array .into_iter // Error .collect ; assert!;
- Allows using
-
FromIterator for [T; n]- Allows using
.collect() - Since it is unsound to have an incomplete array, the collecting fails when the iterator does not have enough elements to fill the array. Thus, since it is a fallible action; there is a new
TryFromIteratortrait. -
let mut numbers_iterator = .into_iter; let array: = numbers_iterator .try_collect // Attempt to collect into the array. This can fail... .unwrap // ...since there needs to be at least 7 elements. ; assert_eq!;
- Allows using
The reason for that is that both interfaces need a structure being able to hold
the partially iterated state: i.e., incomplete arrays. Those have (statically-allocated) memory that might not be initialized: so they are, in a way, like Vectors (except for the fact that their (initial) capacity is fixed and cannot be changed)
That's why having those nice iterator interfaces require writing down a cell-accurate memory ownership management logic very similar to Vec's : hence the StackVec.
Bonus
By exposing the underlying StackVec needed by the aformentioned interfaces, we get full access to a stack-allocated Vec, which can also be useful on its own, since it avoids heap allocation:
-
the heap is a mutable global state and in multi-threaded environments locks are involved,
-
it may require (slow) system allocation
Disclaimer
The performance gain (from using StackVec instead of Vec) is not always guaranteed, since:
-
Vecis the cornerstone of Rust's std library collection and has extremely efficient code written so that LLVM can easily optimize its usage -
Rust's allocator is also incredibly well optimised so the performance penalties from bins management and system allocations (and the locks in a multi-threaded environment) are quite well amortized on average.
Vec vs StackVec basic benchmark
)
)
)
)
Usage
- Add this line to your
Cargo.toml(under[dependencies]):
= "0.0.2"
- Add this to your
.rscode:
extern crate stackvec;
Examples
See the source files for the examples
You can run each example (example_name.rs) with:
WIP
-
into_iter/IntoIteratorandtry_collect/TryFromIteratorfor [Array] -
improve code testing coverage