#stack #stack-memory #memory #fixed-size #unsafe #performance #fastest

microstack

The simplest and the fastest implementation of a fixed-size stack on stack

7 releases

0.0.7 May 15, 2023
0.0.6 May 15, 2023

#310 in Memory management

46 downloads per month

MIT license

26KB
402 lines

cargo crates.io codecov Hits-of-Code Lines of code License docs.rs

This is the simplest and the fastest (faster than Vec!) implementation of a last-in-first-out stack data structure, on stack, when stack elements are Copy implementing primitives. This is basically a wrapper around an uninitialized array. When it is created on stack, its elements contain no specific data. Then, when you push_unchecked(x), the head of the stack is moved forward and x is placed into the element of the array. When you pop_unchecked(), the head is moved backward and the data is retrieved from the array. There are no boundary checks, that's why both push_unchecked() and pop_unchecked() may lead to undefined behavior. Use push() and pop(), which are safer, but slower. For even slower but even safer behavior, you can use try_push() and try_pop().

First, add this to Cargo.toml:

[dependencies]
microstack = "0.0.5"

Then, use it like this (mind the unsafe blocks, they give the fastest performance, but undefined behavior if you go over the stack boundaries):

use microstack::Stack;
let mut s : Stack<&str, 10> = Stack::new(); // allocation on stack
unsafe { s.push_unchecked("foo") }; // no boundary checks here
unsafe { s.push_unchecked("bar") }; // and here
assert_eq!("bar", unsafe { s.pop_unchecked() });
assert_eq!(1, s.len());

Pay attention, here the stack is created with an extra generic argument 10. This is the total size of the stack data structure, which is allocated on stack when ::new() is called.

Read the API documentation.

How to Contribute

First, install Rust and then:

$ cargo test -vv

If everything goes well, fork repository, make changes, send us a pull request. We will review your changes and apply them to the master branch shortly, provided they don't violate our quality standards. To avoid frustration, before sending us your pull request please run cargo test again. Also, run cargo fmt and cargo clippy.

Also, before you start making changes, run benchmarks:

$ rustup run nightly cargo bench

Then, after the changes you make, run it again. Compare the results. If your changes degrade performance, think twice before submitting a pull request.

Dependencies

~170KB