💽

Rustでのデータ処理をrayonクレートで高速化してみる

2024/09/18に公開

単純なシーケンシャル処理でコードを書いていた部分あったのですが、より高速化する方法ないものかと調べていた所rayonクレートなるもので簡単にできるようで、備忘録も兼ねてまとめておこうという記事です。

rayonの導入方法

Cargo.tomlファイルに以下を追記します。

[dependencies]
rayon = "1.10"

もしくはcargo add rayon

サンプルコード

use rayon::prelude::*;

fn main() {
    let numbers: Vec<u32> = (1..101).collect();
    let doubled_numbers: Vec<u32> = numbers.par_iter().map(|&x| x * 2).collect();

    println!("{:?}", doubled_numbers);
}

rayonを導入する場合はiter()par_iter()にすればよいだけです。

処理時間比較

通常のiter()を利用したシーケンシャル処理と、par_iter()を利用した並列処理の実行時間を比較してみます。

use rayon::prelude::*;
use std::time::Instant;

fn main() {
    let data: Vec<u64> = (0..3_000_000).collect();

    // シーケンシャル処理
    let start = Instant::now();
    let _sum: u64 = data.iter().map(|&x| calculation(x)).sum();
    let duration = start.elapsed();
    println!("シーケンシャル処理時間: {:?}", duration);

    // 並列処理
    let start = Instant::now();
    let _sum_parallel: u64 = data.par_iter().map(|&x| calculation(x)).sum();
    let duration = start.elapsed();
    println!("並列処理時間: {:?}", duration);
}

fn calculation(n: u64) -> u64 {
    n * n
}

実行結果は以下のようになりました。

シーケンシャル処理時間: 43.606833ms
並列処理時間: 38.938424ms

Rust Playgroundで簡易的に比較したい都合、データサイズや計算コストがそこまで大きくできてないんですが、恩恵ありそうに見える結果でした。

テクシア テックブログ

Discussion