Crate poolshark

Crate poolshark 

Source
Expand description

Memory pooling is a simple idea, malloc and free can be expensive and so can object initialization, if you malloc and init an object that is used temporarially, and it’s likely you’ll want to use a similar object again in the future, then don’t throw all that work away by freeing it, stick it somewhere until you need it again. This library implements two different flavors of object pooling, local pooling and global pooling.

§Global Pooling

Global pools share objects between threads (see GPooled), an object taken from a global pool will always return to the pool it was taken from. Use this if objects are usually dropped on a different thread than they are created on, for example a producer thread creating objects for consumer threads.

There are several different ways to use global pools. You can use take or take_any to just take objects from thread local global pools. If you need better performance you can use pool or pool_any and then store the pool somewhere. If you don’t have anywhere to store the pool you can use a static LazyLock for a truly global named pool. For example,

use std::{sync::LazyLock, collections::HashMap};
use poolshark::global::{Pool, GPooled};

type Widget = HashMap<usize, usize>;

// create a global static widget pool that will accept up to 1024 widgets with
// up to 64 elements of capacity each
static WIDGETS: LazyLock<Pool<Widget>> = LazyLock::new(|| Pool::new(1024, 64));

fn widget_maker() -> GPooled<Widget> {
    let mut w = WIDGETS.take();
    w.insert(42, 42);
    w
}

fn widget_user(w: GPooled<Widget>) {
    drop(w) // puts the widget back in the WIDGETS pool
}

§Local Pooling

Local pools (see LPooled) always return dropped objects to a thread local structure on the thread that drops them. If your objects are produced and dropped on the same set of threads then a local pool is a good choice. Local pools are significantly faster than global pools because they avoid most atomic operations. Local pools require that your container type implement the unsafe trait IsoPoolable, so they can’t be used with all types.

use poolshark::local::LPooled;
use std::collections::HashMap;

type Widget = HashMap<usize, usize>;

fn widget_maker() -> LPooled<Widget> {
    let mut w = LPooled::<Widget>::default(); // takes from the local pool
    w.insert(42, 42);
    w
}

fn widget_user(w: LPooled<Widget>) {
    drop(w) // puts the widget back in the local pool
}

Modules§

global
Thread safe, lock free, global object pools
local
Thread local object pools
pooled
Implementations of Poolable on various standard types

Macros§

location_id
Generate a globally unique identifier for a source code position

Structs§

Discriminant
Type describing the layout, alignment, and type of a container
LocationId
A globally unique id for a source code position

Traits§

IsoPoolable
Trait for isomorphicly poolable objects.
Poolable
Trait for poolable objects
RawPoolable
Low level global pool trait for maximum control