A thread-safe object pool collection with automatic return.
Some implementations are lockfree : * LinearObjectPool * SpinLockObjectPool
Other use std::Mutex : * MutexObjectPool
And NoneObjectPool basic allocation without pool.
toml
[dependencies]
lockfree-object-pool = "0.1"
rust
extern crate lockfree_object_pool;
The general pool creation looks like this for
rust
let pool = LinearObjectPool::<u32>::new(
|| Default::default(),
|v| {*v = 0; });
And use the object pool
rust
let mut item = pool.pull();
*item = 5;
...
At the end of the scope item return in object pool.
All implementations support same interface :
```rust
struct ObjectPool
}
impl
// for NoneObjectPool // init closure used to create an element pub fn new(init: I) -> Self where I: Fn() -> T + 'static { ... }
pub fn pull(&self) -> Reusable
pub fn pull_owned(self: &Arc
struct Reusable
}
impl<'a, T> DerefMut for Reusable<'a, T> { fn deref_mut(&mut self) -> &mut Self::Target { ... } }
impl<'a, T> Deref for Reusable<'a, T> { type Target = T;
fn deref(&self) -> &Self::Target {
...
}
}
struct OwnedReusable
}
impl<'a, T> DerefMut for OwnedReusable<'a, T> { fn deref_mut(&mut self) -> &mut Self::Target { ... } }
impl<'a, T> Deref for OwnedReusable<'a, T> { type Target = T;
fn deref(&self) -> &Self::Target {
...
}
} ```
All implementation support allocation/desallocation from on or more thread. You only need to wrap the pool in a [std::sync::Arc
] :
rust
let pool = Arc::new(LinearObjectPool::<u32>::new(
|| Default::default(),
|v| {*v = 0; }));
Global report.
ObjectPool | Duration in Monothreading (us) | Duration Multithreading (us)
------------| :----------------------------: | :--------------------------:
NoneObjectPool|1.2848|0.62509
MutexObjectPool|1.3107|1.5178
SpinLockObjectPool|1.3106|1.3684
LinearObjectPool|0.23732|0.38913
[crate 'sharded-slab'
]|1.6264|0.82607
[crate 'object-pool'
]|0.77533|0.26224
Report monothreading and multithreading
ObjectPool | 1 Reader - 1 Writter (ns) | 5 Reader - 1 Writter (ns) | 1 Reader - 5 Writter (ns) | 5 Reader - 5 Writter (ns)
-----------| :-----------------------: | :-----------------------: | :-----------------------: | :-----------------------:
NoneObjectPool|529.75|290.47|926.05|722.35
MutexObjectPool|429.29|207.17|909.88|409.99
SpinLockObjectPool|34.277|182.62|1089.7|483.81
LinearObjectPool|43.876|163.18|365.56|326.92
[crate 'sharded-slab'
]|525.82|775.79|966.87|1289.2
Not supported by [crate 'object-pool'
]
ObjectPool | Duration in Monothreading (ns) | Duration Multithreading (ns)
-----------| :----------------------------: | :--------------------------:
NoneObjectPool|111.81|93.585
MutexObjectPool|26.108|101.86
SpinLockObjectPool|22.441|50.107
LinearObjectPool|7.5379|41.707
[crate 'sharded-slab'
]|7.0394|10.283
[crate 'object-pool'
]|20.517|44.798
Report monothreading and multithreading
[crate 'sharded-slab'
]: I like pull interface but i dislike
Self
[crate 'object-pool'
]: use a spinlock to sync and the performance are pretty good but i dislike :
rust
use object_pool::Pool;
let pool = Pool::<Vec<u8>>::new(32, || Vec::with_capacity(4096);
// ...
let item1 = pool.pull(|| Vec::with_capacity(4096));
// ...
let item2 = pool.pull(|| Vec::with_capacity(4096));
crate 'object-pool'
]toolsbox
])TODO
crate 'object-pool'
] - A thread-safe object pool in rust with mutex crate 'sharded-slab'
] - A lock-free concurrent slabtoolsbox
] - Some object pool implementation en c++