#stack #box #dst #alloc #no-std

nightly no-std nanobox

NanoBox optimization: store small item on stack and fallback to heap for large item

1 unstable release

0.1.0 Aug 24, 2024

#2368 in Data structures

MIT/Apache

26KB
484 lines

nanobox

crates.io

NanoBox optimization: store small item on stack and fallback to heap for large item.

Documentation

Usage

First, add the following to your Cargo.toml:

[dependencies]
nanobox = "0.1"

Unsized Type

There are two ways to have an unsized NanoBox: Using nanobox!() macro (or nb!() if you are lazy) or coercing from a sized NanoBox instance(requires nightly compiler).

Once the feature coerce is enabled, sized NanoBox<T> will be automatically coerced into NanoBox<T: ?Sized> if necessary.

Example

Eliminate heap alloction for small items by NanoBox:

use nanobox::NanoBox;

let small: NanoBox<_> = NanoBox::new([0; 2]);
let large: NanoBox<_> = NanoBox::new([0; 32]);

assert_eq!(small.len(), 2);
assert_eq!(large.len(), 32);

assert_eq!(*small, [0; 2]);
assert_eq!(*large, [0; 32]);

assert!(small.is_heap() == false);
assert!(large.is_heap() == true);

Unsized type

Construct with nanobox!() macro:

use nanobox::NanoBox;
use nanobox::nb;

let array: NanoBox<[usize]> = nb!([0usize, 1]);

assert_eq!(array.len(), 2);
assert_eq!(*array, [0, 1]);

coerce

use nanobox::NanoBox;
 
let array: NanoBox<[usize]> = NanoBox::new([0usize, 1]);

assert_eq!(array.len(), 2);
assert_eq!(*array, [0, 1]);

Any downcasting:

use std::any::Any;
use nanobox::NanoBox;
use nanobox::nb;

let num: NanoBox<dyn Any> = nb!(1234u32);

if let Some(num) = num.downcast_ref::<u32>() {
    assert_eq!(*num, 1234);
} else {
    unreachable!();
}

Capacity

NanoBox has a capacity of 3*usize by default. You can change the capacity by specifying the capacity type parameter.

nanobox_small_item_small_space
                        time:   [494.41 ps 497.13 ps 500.13 ps]
nanobox_small_item_large_space
                        time:   [5.4159 ns 5.4886 ns 5.5663 ns]
box_small_item          
                        time:   [8.8157 ns 8.8830 ns 8.9659 ns]

497.13 ps vs 8.8830 ns for small item in small space. 5.5 ns vs 8.9 ns for small item in large space. NanoBox is faster than Box for small items in small space and large items in large space.

nanobox_large_item_small_space
                        time:   [23.428 ns 23.478 ns 23.523 ns]

nanobox_large_item_large_space
                        time:   [18.288 ns 18.461 ns 18.605 ns]

box_large_item          time:   [16.378 ns 16.438 ns 16.497 ns]

for large items, NanoBox is slower than Box in every cases. you don't want to run into stack overflow, so you should use Box for large items.

License

Licensed under either of

at your option.

Thanks

thanks to @andylokandy for writting smallbox

No runtime deps