開発

[rust] rayonで書き直してみました

前回のコードを元にrayonを使った処理に書き直してみました。

このrayonクレートはおそらく数値計算等CPU負荷が高い処理向きのものだと思いますので使い方が良くないですがこのコードの処理速度は早いです。

デフォルトだとCPU数を判定してスレッド数を決定するようです。カスタムしたい場合はコメントアウトしていますがnum_threadsの値で制御できます。RAYON_NUM_THREADSでも制御できるようです。

今回のrust修行はここまでにしておきます。

MeanStd.Dev.MinMedianMax
real0.2580.3270.2020.2112.546
user0.180.0210.1420.1790.239
sys0.60.1350.5170.5871.53
Thread=4
MeanStd.Dev.MinMedianMax
real0.2630.2950.2050.2162.327
user0.220.0330.1230.220.297
sys0.7050.1410.5550.6791.609
Thread=6
MeanStd.Dev.MinMedianMax
real0.2280.3090.1520.1832.386
user0.2380.0280.1680.2430.292
sys0.8290.1270.6820.8131.559
Thread=8
MeanStd.Dev.MinMedianMax
real0.2490.2840.1970.2092.235
user0.3740.0360.2830.380.437
sys0.7930.1370.70.7791.714
Thread=100
MeanStd.Dev.MinMedianMax
real1.080.2870.9481.0413.065
user6.2610.4625.496.2437.936
sys1.5380.2691.2151.5093.154
Thread=1000
use anyhow::Result; // 1.0.71
use clap::Parser; // 4.3.11

use rayon::prelude::*; // 1.8.0
use std::fs;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
  /// target directory
  #[arg(short, long, default_value_t = String::from(".") )]
  dir: String,
}

fn main() -> Result<()> {
  let args = Args::parse();

  // rayon::ThreadPoolBuilder::new().num_threads(4).build_global().unwrap();

  let dir_string = args.dir.to_string();
  println!("{}", dir_string);

  let mut list_from_thd = vec![dir_string];

  while !list_from_thd.is_empty() {
    let new_dir_list: Vec<_> = list_from_thd
      .into_par_iter()
      .map(|dir| get_dirs(dir).ok().unwrap())
      .flatten()
      .collect();

    list_from_thd = new_dir_list;
  }

  Ok(())
}

fn get_dirs(dir: String) -> Result<Vec<String>> {
  let mut entries = fs::read_dir(dir)?;

  // Folder list
  let mut dirs = Vec::<String>::new();

  while let Some(entry) = entries.next() {
    let entry = entry?;
    let metadata = entry.metadata()?;
    let path = entry.path();
    let path_2 = path.clone();

    let path = path.display().to_string();
    if metadata.is_dir() {
      println!("{}", path);

      dirs.push(path);
    }

    let path = path_2;
    if let Ok(symlink) = fs::read_link(&path) {
      if path.is_dir() {
        println!("{}@ -> {}", path.display(), symlink.display());
      }
    }
  }

  Ok(dirs)
}
Tags: rust
管理人

Recent Posts

CanvaがSerif (Affinity) を買収

私は使ったことがないのですが名前はよく聞…

4週間 ago

Serifのスプリングセール – アドオンが50%オフ

Affinity Photoなどレタッチ…

2か月 ago

音声がロボットのようになるときの対処

リモート会議などでたまに相手の音声がおか…

3か月 ago

Serifのブラックフライデー – 全品40%オフ V1ユーザは更にお得!

恒例のブラックフライデーセールが始まりま…

5か月 ago

[rust] async-stdで書き直してみました

前回のコードをasync-stdで書き直…

6か月 ago

[rust] mutexを使わないバージョン tokio版ディレクトリ再帰的取得

前回の続き。mutexを使わないバージョ…

6か月 ago