Rust中如何用Rayon对HashMap的数据进行分块处理?
问题
是否可以使用Rayon对HashMap中的数据进行分块?我找到的多个分块方法似乎仅支持切片或同类结构。
测试代码如下:
use rayon::prelude::*; use std::collections::HashMap; use log::info; fn main() { let foo = vec![1, 2, 3, 4, 5, 6, 7, 8]; foo.par_chunks(3).for_each(|x| { info!("x: {:?}", x); }); let bar = HashMap::<String, String>::default(); bar.par_chunks(3).for_each(|x| { info!("x: {:?}", x); }); bar.chunks(3).for_each(|x| { info!("x: {:?}", x); }); bar.par_iter().chunks(3).for_each(|x| { info!("x: {:?}", x); }); }
上述代码中Vec部分可以正常编译,但所有HashMap相关的分块尝试都报错「不存在名为xxx的方法」。
补充说明:关于如何在Rayon中使用现有迭代器的问题无法解答我的疑问,我需要的是获取可对HashMap进行分块的迭代器实现方案。
解答
chunks/par_chunks是切片类结构的专属方法,依赖连续内存布局实现。HashMap基于哈希表实现,内存不连续,因此没有原生的分块方法可以直接调用。
你可以借助itertools库的Itertools::chunks方法实现HashMap的分块迭代,示例代码如下:
use itertools::Itertools; use std::collections::HashMap; fn main() { let mut m: HashMap<usize, usize> = HashMap::default(); for n in 0..100 { m.insert(n, 2 * n); } println!("m: {:?}", m); let res: HashMap<usize, usize> = (&m) .into_iter() .chunks(7) .into_iter() .map(|c| c.map(|(a, b)| (a + b, b - a))) .flatten() .collect(); println!("M still usable: {}", m.len()); println!("res: {:?}", res); }
如果需要结合Rayon实现并行分块处理,可以对分块后的迭代器调用par_bridge转为并行迭代器即可,示例如下:
use rayon::prelude::*; use itertools::Itertools; use std::collections::HashMap; use log::info; fn main() { let mut bar = HashMap::<String, String>::default(); // 此处省略向bar插入数据的逻辑 bar.par_iter() .chunks(3) .into_iter() .par_bridge() .for_each(|x| { info!("x: {:?}", x); }); }
内容的提问来源于stack exchange,提问作者Troy Daniels
相关产品推荐
相关产品推荐

