nanobox 0.1.0

`NanoBox` optimization: store small item on stack and fallback to heap for large item.
Documentation
  • Coverage
  • 100%
    4 out of 4 items documented2 out of 3 items with examples
  • Size
  • Source code size: 30.7 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 325.1 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 8s Average build duration of successful builds.
  • all releases: 8s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Repository
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • LemonHX

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