Gankro/collect-rs — pull request #21 by cybergeek94 (2014-12-18 05:06:31+00:00)
Title: `ParVec`: A vector that allows concurrent manipulation of non-overlapping slices.

Vectors can safely be operated on concurrently/in-parallel if the concurrent access is to non-overlapping slices and the vector itself is not mutated (length/capacity/reallocation). This struct takes advantage of that, allowing users to "borrow" non-overlapping slices and send them to other threads.

Can also be mapped in parallel.

I put it in the `proto` module because I assume that means `prototype` and I haven't really tried `ParVec` in the wild yet, though I know it does work.

```
test proto::par_vec::test::par_prime_factors ... bench: 118 ns/iter (+/- 39)
test proto::par_vec::test::seq_prime_factors ... bench: 2010185 ns/iter (+/- 10296)
```

Both benchmarks map a `Vec` to a `Vec>` where each sub-vector is a list of the prime factors of each element in the original vector, which goes from 1 to 1000. The former uses `ParVec::par_map()` on `std::os::num_cpus()` threads while the latter just maps a range.

To be fair to the sequential benchmark, the `par` result might be horribly incorrect. There's a lot of unsafe code in there playing with pointers and raw slices; the parallel result might not be correct at all but the benchmarks would suffer if I added sanity-checking code (I guess not so badly in comparison if the sequential one had it as well). That's a definite TODO.

I gave the parallel benchmark a head-start using a pre-created task pool instead of spinning one up each iteration, which would make it suffer horribly.

I'd run these benchmarks a few more times but `cargo bench --bench ` doesn't want to work, so I'm forced to run the whole suite each time. :(