#! [expect(missing_docs)]
// https://github.com/rust-lang/rust/issues/137561
#! [cfg(feature =
"rayon" )]
use hashbrown::{HashMap, HashSet};
use rayon::iter::{
IntoParallelIterator, IntoParallelRefIterator, IntoParallelRefMutIterator, Parallel
Extend,
ParallelIterator,
};
use std::sync::LazyLock;
macro_rules! assert_eq3 {
($e1:expr, $e2:expr, $e3:expr) => {{
assert_eq!($e1, $e2);
assert_eq!($e1, $e3);
assert_eq!($e2, $e3);
}};
}
static MAP_EMPTY: LazyLock<HashMap<char, u32>> = LazyLock::new(HashMap::new);
static MAP: LazyLock<HashMap<char, u32>> = LazyLock::new(|| {
let mut m = HashMap::new();
m.insert('b' , 20 );
m.insert('a' , 10 );
m.insert('c' , 30 );
m.insert('e' , 50 );
m.insert('f' , 60 );
m.insert('d' , 40 );
m
});
#[ test]
fn map_seq_par_equivalence_iter_empty() {
let vec_seq = MAP_EMPTY.iter().collect::<Vec<_>>();
let vec_par = MAP_EMPTY.par_iter().collect::<Vec<_>>();
assert_eq3!(vec_seq, vec_par, []);
}
#[ test]
fn map_seq_par_equivalence_iter() {
let mut vec_seq = MAP.iter().collect::<Vec<_>>();
let mut vec_par = MAP.par_iter().collect::<Vec<_>>();
assert_eq!(vec_seq, vec_par);
// Do not depend on the exact order of values
let expected_sorted = [
(&'a' , &10 ),
(&'b' , &20 ),
(&'c' , &30 ),
(&'d' , &40 ),
(&'e' , &50 ),
(&'f' , &60 ),
];
vec_seq.sort_unstable();
vec_par.sort_unstable();
assert_eq3!(vec_seq, vec_par, expected_sorted);
}
#[ test]
fn map_seq_par_equivalence_keys_empty() {
let vec_seq = MAP_EMPTY.keys().collect::<Vec<&char>>();
let vec_par = MAP_EMPTY.par_keys().collect::<Vec<&char>>();
let expected: [&char; 0 ] = [];
assert_eq3!(vec_seq, vec_par, expected);
}
#[ test]
fn map_seq_par_equivalence_keys() {
let mut vec_seq = MAP.keys().collect::<Vec<_>>();
let mut vec_par = MAP.par_keys().collect::<Vec<_>>();
assert_eq!(vec_seq, vec_par);
// Do not depend on the exact order of values
let expected_sorted = [&'a' , &'b' , & style='color:blue'>'c' , &'d' , &'e' , &pan style='color:blue'>'f'];
vec_seq.sort_unstable();
vec_par.sort_unstable();
assert_eq3!(vec_seq, vec_par, expected_sorted);
}
#[ test]
fn map_seq_par_equivalence_values_empty() {
let vec_seq = MAP_EMPTY.values().collect::<Vec<_>>();
let vec_par = MAP_EMPTY.par_values().collect::<Vec<_>>();
let expected: [&u32; 0 ] = [];
assert_eq3!(vec_seq, vec_par, expected);
}
#[ test]
fn map_seq_par_equivalence_values() {
let mut vec_seq = MAP.values().collect::<Vec<_>>();
let mut vec_par = MAP.par_values().collect::<Vec<_>>();
assert_eq!(vec_seq, vec_par);
// Do not depend on the exact order of values
let expected_sorted = [&10 , &20 , &an style='color: green'>30, &40 , &>50 , &60 ];
vec_seq.sort_unstable();
vec_par.sort_unstable();
assert_eq3!(vec_seq, vec_par, expected_sorted);
}
#[ test]
fn map_seq_par_equivalence_iter_mut_empty() {
let mut map1 = MAP_EMPTY.clone();
let mut map2 = MAP_EMPTY.clone();
let vec_seq = map1.iter_mut().collect::<Vec<_>>();
let vec_par = map2.par_iter_mut().collect::<Vec<_>>();
assert_eq3!(vec_seq, vec_par, []);
}
#[ test]
fn map_seq_par_equivalence_iter_mut() {
let mut map1 = MAP.clone();
let mut map2 = MAP.clone();
let mut vec_seq = map1.iter_mut().collect::<Vec<_>>();
let mut vec_par = map2.par_iter_mut().collect::<Vec<_>>();
assert_eq!(vec_seq, vec_par);
// Do not depend on the exact order of values
let expected_sorted = [
(&'a' , &mut 10 ),
(&'b' , &mut 20 ),
(&'c' , &mut 30 ),
(&'d' , &mut 40 ),
(&'e' , &mut 50 ),
(&'f' , &mut 60 ),
];
vec_seq.sort_unstable();
vec_par.sort_unstable();
assert_eq3!(vec_seq, vec_par, expected_sorted);
}
#[ test]
fn map_seq_par_equivalence_values_mut_empty() {
let mut map1 = MAP_EMPTY.clone();
let mut map2 = MAP_EMPTY.clone();
let vec_seq = map1.values_mut().collect::<Vec<_>>();
let vec_par = map2.par_values_mut().collect::<Vec<_>>();
let expected: [&u32; 0 ] = [];
assert_eq3!(vec_seq, vec_par, expected);
}
#[ test]
fn map_seq_par_equivalence_values_mut() {
let mut map1 = MAP.clone();
let mut map2 = MAP.clone();
let mut vec_seq = map1.values_mut().collect::<Vec<_>>();
let mut vec_par = map2.par_values_mut().collect::<Vec<_>>();
assert_eq!(vec_seq, vec_par);
// Do not depend on the exact order of values
let expected_sorted = [&mut 10 , &mut 20 , &an style='color:red'>mut 30 , &mut 40 , &mut 50 , &mut 60 ];
vec_seq.sort_unstable();
vec_par.sort_unstable();
assert_eq3!(vec_seq, vec_par, expected_sorted);
}
#[ test]
fn map_seq_par_equivalence_into_iter_empty() {
let vec_seq = MAP_EMPTY.clone().into_iter().collect::<Vec<_>>();
let vec_par = MAP_EMPTY.clone().into_par_iter().collect::<Vec<_>>();
assert_eq3!(vec_seq, vec_par, []);
}
#[ test]
fn map_seq_par_equivalence_into_iter() {
let mut vec_seq = MAP.clone().into_iter().collect::<Vec<_>>();
let mut vec_par = MAP.clone().into_par_iter().collect::<Vec<_>>();
assert_eq!(vec_seq, vec_par);
// Do not depend on the exact order of values
let expected_sorted = [
('a' , 10 ),
('b' , 20 ),
('c' , 30 ),
('d' , 40 ),
('e' , 50 ),
('f' , 60 ),
];
vec_seq.sort_unstable();
vec_par.sort_unstable();
assert_eq3!(vec_seq, vec_par, expected_sorted);
}
static MAP_VEC_EMPTY: &[(char, u32)] = &[];
static MAP_VEC: &[(char, u32)] = &[
('b' , 20 ),
('a' , 10 ),
('c' , 30 ),
('e' , 50 ),
('f' , 60 ),
('d' , 40 ),
];
#[ test]
fn map_seq_par_equivalence_collect_empty() {
let map_expected = MAP_EMPTY.clone();
let map_seq = MAP_VEC_EMPTY.iter().copied().collect::<HashMap<_, _>>();
let map_par = MAP_VEC_EMPTY.par_iter().copied().collect::<HashMap<_, _>>();
assert_eq!(map_seq, map_par);
assert_eq!(map_seq, map_expected);
assert_eq!(map_par, map_expected);
}
#[ test]
fn map_seq_par_equivalence_collect() {
let map_expected = MAP.clone();
let map_seq = MAP_VEC.iter().copied().collect::<HashMap<_, _>>();
let map_par = MAP_VEC.par_iter().copied().collect::<HashMap<_, _>>();
assert_eq!(map_seq, map_par);
assert_eq!(map_seq, map_expected);
assert_eq!(map_par, map_expected);
}
static MAP_EXISTING_EMPTY: LazyLock<HashMap<char, u32>> = LazyLock::new(HashMap::new);
static MAP_EXISTING: LazyLock<HashMap<char, u32>> = LazyLock::new(|| {
let mut m = HashMap::new();
m.insert('b' , 20 );
m.insert('a' , 10 );
m
});
static MAP_EXTENSION_EMPTY: &[(char, u32)] = &[];
static MAP_EXTENSION: &[(char, u32)] = &[('c' , 30 ), ('e' , 50 ), ('f' , 60 ), ('d' , 40 )];
#[ test]
fn map_seq_par_equivalence_existing_empty_extend_empty() {
let expected = HashMap::new();
let mut map_seq = MAP_EXISTING_EMPTY.clone();
let mut map_par = MAP_EXISTING_EMPTY.clone();
map_seq.extend(MAP_EXTENSION_EMPTY.iter().copied());
map_par.par_extend(MAP_EXTENSION_EMPTY.par_iter().copied());
assert_eq3!(map_seq, map_par, expected);
}
#[ test]
fn map_seq_par_equivalence_existing_empty_extend() {
let expected = MAP_EXTENSION.iter().copied().collect::<HashMap<_, _>>();
let mut map_seq = MAP_EXISTING_EMPTY.clone();
let mut map_par = MAP_EXISTING_EMPTY.clone();
map_seq.extend(MAP_EXTENSION.iter().copied());
map_par.par_extend(MAP_EXTENSION.par_iter().copied());
assert_eq3!(map_seq, map_par, expected);
}
#[ test]
fn map_seq_par_equivalence_existing_extend_empty() {
let expected = MAP_EXISTING.clone();
let mut map_seq = MAP_EXISTING.clone();
let mut map_par = MAP_EXISTING.clone();
map_seq.extend(MAP_EXTENSION_EMPTY.iter().copied());
map_par.par_extend(MAP_EXTENSION_EMPTY.par_iter().copied());
assert_eq3!(map_seq, map_par, expected);
}
#[ test]
fn map_seq_par_equivalence_existing_extend() {
let expected = MAP.clone();
let mut map_seq = MAP_EXISTING.clone();
let mut map_par = MAP_EXISTING.clone();
map_seq.extend(MAP_EXTENSION.iter().copied());
map_par.par_extend(MAP_EXTENSION.par_iter().copied());
assert_eq3!(map_seq, map_par, expected);
}
static SET_EMPTY: LazyLock<HashSet<char>> = LazyLock::new(HashSet::new);
static SET: LazyLock<HashSet<char>> = LazyLock::new(|| {
let mut s = HashSet::new();
s.insert('b' );
s.insert('a' );
s.insert('c' );
s.insert('e' );
s.insert('f' );
s.insert('d' );
s
});
#[ test]
fn set_seq_par_equivalence_iter_empty() {
let vec_seq = SET_EMPTY.iter().collect::<Vec<_>>();
let vec_par = SET_EMPTY.par_iter().collect::<Vec<_>>();
let expected: [&char; 0 ] = [];
assert_eq3!(vec_seq, vec_par, expected);
}
#[ test]
fn set_seq_par_equivalence_iter() {
let mut vec_seq = SET.iter().collect::<Vec<_>>();
let mut vec_par = SET.par_iter().collect::<Vec<_>>();
assert_eq!(vec_seq, vec_par);
// Do not depend on the exact order of values
let expected_sorted = [&'a' , &'b' , & style='color:blue'>'c' , &'d' , &'e' , &pan style='color:blue'>'f'];
vec_seq.sort_unstable();
vec_par.sort_unstable();
assert_eq3!(vec_seq, vec_par, expected_sorted);
}
#[ test]
fn set_seq_par_equivalence_into_iter_empty() {
let vec_seq = SET_EMPTY.clone().into_iter().collect::<Vec<_>>();
let vec_par = SET_EMPTY.clone().into_par_iter().collect::<Vec<_>>();
// Work around type inference failure introduced by rend dev-dependency.
let empty: [char; 0 ] = [];
assert_eq3!(vec_seq, vec_par, empty);
}
#[ test]
fn set_seq_par_equivalence_into_iter() {
let mut vec_seq = SET.clone().into_iter().collect::<Vec<_>>();
let mut vec_par = SET.clone().into_par_iter().collect::<Vec<_>>();
assert_eq!(vec_seq, vec_par);
// Do not depend on the exact order of values
let expected_sorted = ['a' , 'b' , 'c' , 'd' , 'e' , 'f' ];
vec_seq.sort_unstable();
vec_par.sort_unstable();
assert_eq3!(vec_seq, vec_par, expected_sorted);
}
static SET_VEC_EMPTY: &[char] = &[];
static SET_VEC: &[char] = &['b' , 'a' , 'c' , 'e' , 'f' , 'd' ];
#[ test]
fn set_seq_par_equivalence_collect_empty() {
let set_expected = SET_EMPTY.clone();
let set_seq = SET_VEC_EMPTY.iter().copied().collect::<HashSet<_>>();
let set_par = SET_VEC_EMPTY.par_iter().copied().collect::<HashSet<_>>();
assert_eq!(set_seq, set_par);
assert_eq!(set_seq, set_expected);
assert_eq!(set_par, set_expected);
}
#[ test]
fn set_seq_par_equivalence_collect() {
let set_expected = SET.clone();
let set_seq = SET_VEC.iter().copied().collect::<HashSet<_>>();
let set_par = SET_VEC.par_iter().copied().collect::<HashSet<_>>();
assert_eq!(set_seq, set_par);
assert_eq!(set_seq, set_expected);
assert_eq!(set_par, set_expected);
}
static SET_EXISTING_EMPTY: LazyLock<HashSet<char>> = LazyLock::new(HashSet::new);
static SET_EXISTING: LazyLock<HashSet<char>> = LazyLock::new(|| {
let mut s = HashSet::new();
s.insert('b' );
s.insert('a' );
s
});
static SET_EXTENSION_EMPTY: &[char] = &[];
static SET_EXTENSION: &[char] = &['c' , 'e' , 'f' , 'd' ];
#[ test]
fn set_seq_par_equivalence_existing_empty_extend_empty() {
let expected = HashSet::new();
let mut set_seq = SET_EXISTING_EMPTY.clone();
let mut set_par = SET_EXISTING_EMPTY.clone();
set_seq.extend(SET_EXTENSION_EMPTY.iter().copied());
set_par.par_extend(SET_EXTENSION_EMPTY.par_iter().copied());
assert_eq3!(set_seq, set_par, expected);
}
#[ test]
fn set_seq_par_equivalence_existing_empty_extend() {
let expected = SET_EXTENSION.iter().copied().collect::<HashSet<_>>();
let mut set_seq = SET_EXISTING_EMPTY.clone();
let mut set_par = SET_EXISTING_EMPTY.clone();
set_seq.extend(SET_EXTENSION.iter().copied());
set_par.par_extend(SET_EXTENSION.par_iter().copied());
assert_eq3!(set_seq, set_par, expected);
}
#[ test]
fn set_seq_par_equivalence_existing_extend_empty() {
let expected = SET_EXISTING.clone();
let mut set_seq = SET_EXISTING.clone();
let mut set_par = SET_EXISTING.clone();
set_seq.extend(SET_EXTENSION_EMPTY.iter().copied());
set_par.par_extend(SET_EXTENSION_EMPTY.par_iter().copied());
assert_eq3!(set_seq, set_par, expected);
}
#[ test]
fn set_seq_par_equivalence_existing_extend() {
let expected = SET.clone();
let mut set_seq = SET_EXISTING.clone();
let mut set_par = SET_EXISTING.clone();
set_seq.extend(SET_EXTENSION.iter().copied());
set_par.par_extend(SET_EXTENSION.par_iter().copied());
assert_eq3!(set_seq, set_par, expected);
}
static SET_A: LazyLock<HashSet<char>> =
LazyLock::new(|| ['a' , 'b' , 'c' , 'd' ].iter().copied().collect());
static SET_B: LazyLock<HashSet<char>> =
LazyLock::new(|| ['a' , 'b' , 'e' , 'f' ].iter().copied().collect());
static SET_DIFF_AB: LazyLock<HashSet<char>> =
LazyLock::new(|| ['c' , 'd' ].iter().copied().collect());
static SET_DIFF_BA: LazyLock<HashSet<char>> =
LazyLock::new(|| ['e' , 'f' ].iter().copied().collect());
static SET_SYMM_DIFF_AB: LazyLock<HashSet<char>> =
LazyLock::new(|| ['c' , 'd' , 'e' , 'f' ].iter().copied().collect());
static SET_INTERSECTION_AB: LazyLock<HashSet<char>> =
LazyLock::new(|| ['a' , 'b' ].iter().copied().collect());
static SET_UNION_AB: LazyLock<HashSet<char>> =
LazyLock::new(|| ['a' , 'b' , 'c' , 'd' , 'e' , 'f' ].iter().copied().collect());
#[ test]
fn set_seq_par_equivalence_difference() {
let diff_ab_seq = SET_A.difference(&*SET_B).copied().collect::<HashSet<_>>();
let diff_ab_par = SET_A
.par_difference(&*SET_B)
.copied()
.collect::<HashSet<_>>();
assert_eq3!(diff_ab_seq, diff_ab_par, *SET_DIFF_AB);
let diff_ba_seq = SET_B.difference(&*SET_A).copied().collect::<HashSet<_>>();
let diff_ba_par = SET_B
.par_difference(&*SET_A)
.copied()
.collect::<HashSet<_>>();
assert_eq3!(diff_ba_seq, diff_ba_par, *SET_DIFF_BA);
}
#[ test]
fn set_seq_par_equivalence_symmetric_difference() {
let symm_diff_ab_seq = SET_A
.symmetric_difference(&*SET_B)
.copied()
.collect::<HashSet<_>>();
let symm_diff_ab_par = SET_A
.par_symmetric_difference(&*SET_B)
.copied()
.collect::<HashSet<_>>();
assert_eq3!(symm_diff_ab_seq, symm_diff_ab_par, *SET_SYMM_DIFF_AB);
}
#[ test]
fn set_seq_par_equivalence_intersection() {
let intersection_ab_seq = SET_A.intersection(&*SET_B).copied().collect::<HashSet<_>>();
let intersection_ab_par = SET_A
.par_intersection(&*SET_B)
.copied()
.collect::<HashSet<_>>();
assert_eq3!(
intersection_ab_seq,
intersection_ab_par,
*SET_INTERSECTION_AB
);
}
#[ test]
fn set_seq_par_equivalence_union() {
let union_ab_seq = SET_A.union(&*SET_B).copied().collect::<HashSet<_>>();
let union_ab_par = SET_A.par_union(&*SET_B).copied().collect::<HashSet<_>>();
assert_eq3!(union_ab_seq, union_ab_par, *SET_UNION_AB);
}
Messung V0.5 in Prozent C=74 H=92 G=83
¤ Dauer der Verarbeitung: 0.6 Sekunden
¤
*© Formatika GbR, Deutschland