Rustのimageのピクセル処理をRayonで並列化する
これ↓を書くときに困ったのでメモ。
Rustのimageでピクセルごとの処理を書くときはenumerate_pixels_mut()
を使うらしい。
これにRayonのpar_iter_mut()
を組み合わせて、処理を並列化してみる。
extern crate image; extern crate rayon; use image::{Rgb, RgbImage}; use rayon::prelude::*; fn gen_img() -> RgbImage { let mut img = RgbImage::new(1200, 800); img.enumerate_pixels_mut() .collect::<Vec<(u32, u32, &mut Rgb<u8>)>>() .par_iter_mut() .for_each(|(x, y, pixel)| { pixel[0] = (255.0 * (*x as f64 / 1200.0)) as u8; pixel[1] = (255.0 * (*y as f64 / 1200.0)) as u8; pixel[2] = 128; }); img } fn main() { let img = gen_img(); img.save("sample.png").unwrap(); }
これで並列化できてるはず。 一応ベンチマークを取ってみる。
iter_mut()のとき
bench: 22,650,690 ns/iter (+/- 2,139,697)
par_iter_mut()のとき
bench: 16,251,080 ns/iter (+/- 1,763,219)
やはりこの程度の軽い処理ではあまり差が出ないようだが、ちゃんと並列演算してくれてるっぽい。
まだIteratorの扱い方を完全に把握できていないので勉強したい。