Skip to content

Commit

Permalink
Add fast paths avoiding chunking for various methods in `iter_concurr…
Browse files Browse the repository at this point in the history
…ent_limit` if `concurrent_limit` is zero
  • Loading branch information
LDeakin committed Feb 16, 2024
1 parent 3a3d2e8 commit 72efa94
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Changed
- Minor documentation improvements
- Add fast paths avoiding chunking for various methods in `iter_concurrent_limit` if `concurrent_limit` is zero

## Fixed
- Fixed `iter_subdivide` if supplied with an empty iterator
Expand Down
33 changes: 25 additions & 8 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ pub fn iter_subdivide<I: IndexedParallelIterator>(num_chunks: usize, iterator: I
/// # Arguments
/// The macro arguments are `(concurrent_limit, parallel_iterator, method, function)`:
/// - `concurrent_limit` is a [`usize`] specifying the maximum concurrent executions of `function`.
/// - A `concurrent_limit` of zero means no concurrent limit. Some methods will skip internal chunking in this case.
/// - `parallel_iterator` is an iterator implementing [`rayon::iter::IndexedParallelIterator`].
/// - `method` is the name of a supported [`ParallelIterator`](rayon::iter::ParallelIterator)/[`IndexedParallelIterator`] method:
/// - Only methods which call a supplied function are supported.
Expand Down Expand Up @@ -249,14 +250,22 @@ pub fn iter_subdivide<I: IndexedParallelIterator>(num_chunks: usize, iterator: I
#[macro_export]
macro_rules! iter_concurrent_limit {
( $concurrent_limit:expr, $iterator:expr, for_each, $op:expr ) => {{
let chunks = $crate::iter_subdivide($concurrent_limit, $iterator);
chunks.for_each(|chunk| chunk.into_iter().for_each($op))
if $concurrent_limit == 0 {
$iterator.for_each($op)
} else {
let chunks = $crate::iter_subdivide($concurrent_limit, $iterator);
chunks.for_each(|chunk| chunk.into_iter().for_each($op))
}
}};
// TODO: for_each_with?
// TODO: for_each_init?
( $concurrent_limit:expr, $iterator:expr, try_for_each, $op:expr ) => {{
let chunks = $crate::iter_subdivide($concurrent_limit, $iterator);
chunks.try_for_each(|chunk| chunk.into_iter().try_for_each($op))
if $concurrent_limit == 0 {
$iterator.try_for_each($op)
} else {
let chunks = $crate::iter_subdivide($concurrent_limit, $iterator);
chunks.try_for_each(|chunk| chunk.into_iter().try_for_each($op))
}
}};
// TODO: try_for_each_with?
// TODO: try_for_each_init?
Expand Down Expand Up @@ -317,12 +326,20 @@ macro_rules! iter_concurrent_limit {
// TODO: find_map_first?
// TODO: find_map_last?
( $concurrent_limit:expr, $iterator:expr, any, $predicate:expr ) => {{
let chunks = $crate::iter_subdivide($concurrent_limit, $iterator);
chunks.any(|chunk| chunk.into_iter().any($predicate))
if $concurrent_limit == 0 {
$iterator.any($predicate)
} else {
let chunks = $crate::iter_subdivide($concurrent_limit, $iterator);
chunks.any(|chunk| chunk.into_iter().any($predicate))
}
}};
( $concurrent_limit:expr, $iterator:expr, all, $predicate:expr ) => {{
let chunks = $crate::iter_subdivide($concurrent_limit, $iterator);
chunks.all(|chunk| chunk.into_iter().all($predicate))
if $concurrent_limit == 0 {
$iterator.all($predicate)
} else {
let chunks = $crate::iter_subdivide($concurrent_limit, $iterator);
chunks.all(|chunk| chunk.into_iter().all($predicate))
}
}};
// TODO: partition?
// TODO: partition_map?
Expand Down

0 comments on commit 72efa94

Please sign in to comment.