zslayton / lifeguard

An object pool manager in Rust
MIT License
195 stars 13 forks source link

Support Arc in addition to Rc and & #19

Open zslayton opened 5 years ago

zslayton commented 5 years ago

Pool values are currently neither Send nor Sync, which precludes some interesting use cases around rayon and crossbeam.

Add support for creating a Pool that emits Arc references once Generic Associated Types (rust-lang/rust/issues/44265) lands.

chachi commented 5 years ago

Is there a reason (besides avoiding code duplication) that this feature is blocked on GATs landing?

zslayton commented 5 years ago

It's a combination of code duplication and lack of development time. I have a branch with a near-complete refactor somewhere that would minimize the duplication, but it changes the API somewhat so I've been waiting for the opportunity to collect some feedback before pulling the trigger. The change (described in this thread) would allow for the removal of virtual dispatch, make it easier to make a Pool of values for data types you don't own, and allow different pointer types under the hood.

In the meantime, if someone were to submit a PR adding support for Arc using code duplication (along with benchmarks/tests), I'd be happy to review it!

orium commented 5 years ago

You might want to take a look at archery. (Disclaimer: I'm the author :slightly_smiling_face:)

SethDusek commented 5 years ago

I think being able to share the Pool itself across threads will also be nice too. Currently Pool is not Sync as it uses an Rc/RefCell internally.

zslayton commented 4 years ago

After some experimentation on a local branch, benchmarks show that using an Arc<Mutex<_>> or an Arc<RwLock<_>> instead of Rc<RefCell<_>> degrades performance to the point that just using the system allocator is a huge win.

This single-threaded benchmark simply allocated blank Strings in a tight loop:

test tests::allocation_standard     ... bench:   8,609,401 ns/iter (+/- 5,116,983) // System allocator
test tests::allocation_pooled       ... bench:   4,789,584 ns/iter (+/- 144,361)   // &RefCell<_>
test tests::allocation_pooled_rc    ... bench:   6,293,622 ns/iter (+/- 190,541)   // Rc<RefCell<_>>
test tests::allocation_pooled_sync  ... bench:  14,181,916 ns/iter (+/- 375,415)   // &RwLock<_>
test tests::allocation_pooled_arc   ... bench:  22,166,528 ns/iter (+/- 490,503)   // Arc<RwLock<_>>

Note that the Mutex and RwLock types being used here are from the parking_lot crate. Their equivalents in the standard library were much, much slower.

I'd still like to offer this feature, but I'll need to look into other concurrency strategies.