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
TryFromIterator
trait. -
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 Vec
tors (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:
-
Vec
is 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
.rs
code:
extern crate stackvec;
Examples
See the source files for the examples
You can run each example (example_name.rs
) with:
WIP
-
into_iter
/IntoIterator
andtry_collect
/TryFromIterator
for [Array
] -
improve code testing coverage