【问题标题】:How do I use Rayon with an existing iterator?如何将 Rayon 与现有的迭代器一起使用?
【发布时间】:2018-08-02 00:12:30
【问题描述】:

在进行一些过滤后,我将正则表达式转换为 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();

【问题讨论】:

  • par_iter 如文档中所述?
  • 我试过了,但是得到了以下错误:error[E0599]: no method named par_iter found for type regex::CaptureMatches&lt;'_, '_&gt; in the current scope --> src/main.rs:24:58 | 24 |让网址: HashSet = re.captures_iter(&contents).par_iter() | ^^^^^^^^ | = 注意:方法par_iter 存在,但不满足以下特征界限:regex::CaptureMatches&lt;'_, '_&gt; : rayon::iter::IntoParallelRefIterator

标签: rust rayon


【解决方案1】:

现在可以使用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!"]);

【讨论】:

  • 请注意,您可以使用rayon::prelude::* 自动获取ParallelBridgeParallelIterator 等特征。 (不过,这可能是一个口味问题,但我发现手动命名 traits 并不能提高模块的可读性。)此外,人造丝有 its own sort 你可能想用它来按多个核心对输出进行排序。
【解决方案2】:

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


最小复制:

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();
}

你不能那样做。 Here都是这个特性的实现者,分别是:

  • 二进制堆
  • BTreeMap
  • BTreeSet
  • 哈希映射
  • 哈希集
  • 链表
  • VecDeque
  • 选项
  • 范围
  • 结果
  • 切片/数组

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

【讨论】:

    猜你喜欢
    • 2019-08-09
    • 1970-01-01
    • 2013-07-16
    • 2022-10-07
    • 1970-01-01
    • 2013-05-30
    • 1970-01-01
    • 2021-05-07
    • 1970-01-01
    相关资源
    最近更新 更多