Skip to main content

Module parallelism

Module parallelism 

Source
Expand description

§Thread Safety and Parallelism

The library provides a parallel trait hierarchy that mirrors the sequential one. All par_* free functions accept plain impl Fn + Send + Sync closures: no wrapper types required. Element types require A: Send; closures require Send + Sync.

---
config:
  layout: elk
---
graph TD
    ParFunctor --> ParFilterable
    ParCompactable --> ParFilterable
    ParFunctor --> ParFunctorWithIndex
    ParFoldable --> ParFoldableWithIndex
    ParFilterable --> ParFilterableWithIndex
    ParFoldableWithIndex --> ParFilterableWithIndex
Parallel traitOperationsSupertraits
ParFunctorpar_mapKind
ParCompactablepar_compact, par_separateKind
ParFilterablepar_filter_map, par_filterParFunctor + ParCompactable
ParFoldablepar_fold_mapKind
ParFunctorWithIndexpar_map_with_indexParFunctor + FunctorWithIndex
ParFoldableWithIndexpar_fold_map_with_indexParFoldable + FoldableWithIndex
ParFilterableWithIndexpar_filter_map_with_indexParFilterable + ParFoldableWithIndex + WithIndex

ParFilterable provides default implementations of par_filter_map and par_filter derived from par_map + par_compact; types can override them for single-pass efficiency.

  • SendCloneFn: Thread-safe cloneable function wrappers with Send + Sync bounds. Implemented by ArcFnBrand.
  • Rayon Support: When the rayon feature is enabled, par_* functions use rayon for true parallel execution. Otherwise they fall back to sequential equivalents.
§Parallel By-Reference Traits

A parallel by-reference hierarchy mirrors the parallel one but closures receive &A instead of consuming A. Elements require A: Send + Sync (for rayon’s par_iter() which needs &A: Send, equivalent to A: Sync).

---
config:
  layout: elk
---
graph TD
    ParRefFunctor --> ParRefFilterable
    ParCompactable --> ParRefFilterable
    ParRefFunctor --> ParRefFunctorWithIndex
    ParRefFoldable --> ParRefFoldableWithIndex
    ParRefFilterable --> ParRefFilterableWithIndex
    ParRefFoldableWithIndex --> ParRefFilterableWithIndex
Par-Ref traitOperationsSupertraits
ParRefFunctorpar_ref_mapRefFunctor
ParRefFoldablepar_ref_fold_mapRefFoldable
ParRefFilterablepar_ref_filter_map, par_ref_filterParRefFunctor + ParCompactable
ParRefFunctorWithIndexpar_ref_map_with_indexParRefFunctor + RefFunctorWithIndex
ParRefFoldableWithIndexpar_ref_fold_map_with_indexParRefFoldable + RefFoldableWithIndex
ParRefFilterableWithIndexpar_ref_filter_map_with_index, par_ref_filter_with_indexParRefFilterable + RefFilterableWithIndex

Key benefit: par_ref_filter_map(|x: &A| ...) avoids consuming elements that get filtered out. Only elements that survive the filter are transformed. Implemented for Vec (using par_iter()) and CatList (collecting to Vec for rayon).

use fp_library::{
	brands::*,
	functions::*,
};

let v = vec![1, 2, 3, 4, 5];
// Map in parallel (uses rayon if feature is enabled)
let doubled: Vec<i32> = par_map::<VecBrand, _, _>(|x: i32| x * 2, v.clone());
assert_eq!(doubled, vec![2, 4, 6, 8, 10]);
// Compact options in parallel
let opts = vec![Some(1), None, Some(3), None, Some(5)];
let compacted: Vec<i32> = par_compact::<VecBrand, _>(opts);
assert_eq!(compacted, vec![1, 3, 5]);
// Fold in parallel
let result = par_fold_map::<VecBrand, _, _>(|x: i32| x.to_string(), v);
assert_eq!(result, "12345".to_string());