Как получить индекс чанка в Районе par_chunks_mut - PullRequest
1 голос
/ 15 апреля 2020

У меня есть некоторые данные, и я хочу обработать их и использовать для заполнения уже существующего массива. Например, предположим, что я хочу повторить каждое значение 4 раза ( детская площадка ):

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[?];
        }
    });
}

Это почти работает, но Район не передает мне индекс чанка, поэтому я не могу поставить что-нибудь в input[?]. Есть ли эффективное решение?

Ответы [ 2 ]

3 голосов
/ 15 апреля 2020

Rayon предоставляет функцию enumerate() для большинства своих итераторов, которая работает так же, как непараллельный аналог:

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];
    }
});
3 голосов
/ 15 апреля 2020

Самое простое, что нужно сделать, это вообще избежать необходимости в индексе. В этом примере мы можем просто заархивировать итераторы:

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

Для традиционных итераторов этот стиль реализации полезен, поскольку позволяет избежать ненужных проверок границ, которые в противном случае были бы обработаны итератором. Я не уверен, что Rayon извлекает выгоду из точно такой же вещи, но я также не вижу причин, по которым это не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...