10

HashSet在进行一些过滤后,我将正则表达式变成了。我正在尝试将它与 Rayon 一起使用,但我无法弄清楚如何在不先将 Rayon 转换为向量的情况下使 Rayon 与现有迭代器一起使用。这可能吗?

let re = Regex::new("url=\"(?P<url>.+?)\"").unwrap();
let urls: HashSet<String> = re.captures_iter(&contents)
    .map(|m| Url::parse(m.name("url").unwrap().as_str()))
    .filter(|parsed_url| parsed_url.is_ok())
    .map(|parsed_url| parsed_url.unwrap())
    .filter(|parsed_url| parsed_url.has_host())
    .map(|parsed_url| parsed_url.into_string())
    .collect();
4

2 回答 2

13

现在可以使用ParallelBridge

use rayon::iter::ParallelBridge;
use rayon::prelude::ParallelIterator;
use std::sync::mpsc::channel;

let rx = {
    let (tx, rx) = channel();

    tx.send("one!");
    tx.send("two!");
    tx.send("three!");

    rx
};

let mut output: Vec<&'static str> = rx.into_iter().par_bridge().collect();
output.sort_unstable();

assert_eq!(&*output, &["one!", "three!", "two!"]);
于 2019-01-15T14:50:04.827 回答
9

这个答案对于最后一个版本的人造丝来说已经过时了。请参阅其他答案以获取可能的解决方案。它可能适用于您的用例,也可能不适用于您的用例。


最小复制:

extern crate rayon;

use rayon::prelude::*;

fn main() {
    let v = vec![1_i32, 2, 3, 4].into_iter();

    // no method named `par_iter` found for type `std::vec::IntoIter<i32>`
    let _ = v.par_iter().sum();
}

你不能这样做。以下是此功能的所有实现者,即:

  • 二叉堆
  • BTreeMap
  • B树集
  • 哈希映射
  • 哈希集
  • 链表
  • 维克德克
  • 选项
  • 范围
  • 结果
  • 切片/数组

我认为你不能并行化它们的原因是因为迭代器是懒惰的。迭代器基本上是一个当前项Option<Item>和一个next()方法。您不能将其分成两部分以在不同的线程中执行它们。

于 2018-02-22T12:24:28.010 回答