1

我有一些数据,我想处理它并用它来填充一个已经存在的数组。例如,假设我想将每个值重复 4 次(playground):

use rayon::prelude::*; // 1.3.0

fn main() {
    let input = vec![4, 7, 2, 3, 5, 8];

    // This already exists.
    let mut output = vec![0; input.len() * 4];

    output.par_chunks_mut(4).for_each(|slice| {
        for x in slice.iter_mut() {
            *x = input[?];
        }
    });
}

这几乎可以工作,但 Rayon 没有将块索引传递给我,所以我不能在input[?]. 有没有有效的解决方案?

4

2 回答 2

5

最简单的做法是完全避免使用索引。对于这个例子,我们可以压缩迭代器:

use rayon::prelude::*; // 1.3.0

fn main() {
    let input = vec![4, 7, 2, 3, 5, 8];
    let mut output = vec![0; input.len() * 4];

    // Can also use `.zip(&input)` if you don't want to give up ownership
    output.par_chunks_mut(4).zip(input).for_each(|(o, i)| {
        for o in o {
            *o = i
        }
    });

    println!("{:?}", output)
}

对于传统的迭代器,这种实现方式是有益的,因为它避免了不必要的边界检查,否则这些检查将由迭代器处理。我不确定人造丝是否会从完全相同的事情中受益,但我也看不出有任何理由不会。

于 2020-04-15T14:12:18.223 回答
4

Rayonenumerate()为其大多数迭代器提供了一个函数,其工作方式与非并行对应物一样:

let input = vec![4, 7, 2, 3, 5, 8];
let mut output = vec![0; input.len() * 4];

output.par_chunks_mut(4).enumerate().for_each(|(i, slice)| {
    for x in slice.iter_mut() {
        *x = input[i];
    }
});
于 2020-04-15T14:17:53.993 回答