前回のコードを元にrayonを使った処理に書き直してみました。
このrayonクレートはおそらく数値計算等CPU負荷が高い処理向きのものだと思いますので使い方が良くないですがこのコードの処理速度は早いです。
デフォルトだとCPU数を判定してスレッド数を決定するようです。カスタムしたい場合はコメントアウトしていますがnum_threadsの値で制御できます。RAYON_NUM_THREADSでも制御できるようです。
今回のrust修行はここまでにしておきます。
| Mean | Std.Dev. | Min | Median | Max |
real | 0.258 | 0.327 | 0.202 | 0.211 | 2.546 |
user | 0.18 | 0.021 | 0.142 | 0.179 | 0.239 |
sys | 0.6 | 0.135 | 0.517 | 0.587 | 1.53 |
Thread=4 | Mean | Std.Dev. | Min | Median | Max |
real | 0.263 | 0.295 | 0.205 | 0.216 | 2.327 |
user | 0.22 | 0.033 | 0.123 | 0.22 | 0.297 |
sys | 0.705 | 0.141 | 0.555 | 0.679 | 1.609 |
Thread=6 | Mean | Std.Dev. | Min | Median | Max |
real | 0.228 | 0.309 | 0.152 | 0.183 | 2.386 |
user | 0.238 | 0.028 | 0.168 | 0.243 | 0.292 |
sys | 0.829 | 0.127 | 0.682 | 0.813 | 1.559 |
Thread=8 | Mean | Std.Dev. | Min | Median | Max |
real | 0.249 | 0.284 | 0.197 | 0.209 | 2.235 |
user | 0.374 | 0.036 | 0.283 | 0.38 | 0.437 |
sys | 0.793 | 0.137 | 0.7 | 0.779 | 1.714 |
Thread=100 | Mean | Std.Dev. | Min | Median | Max |
real | 1.08 | 0.287 | 0.948 | 1.041 | 3.065 |
user | 6.261 | 0.462 | 5.49 | 6.243 | 7.936 |
sys | 1.538 | 0.269 | 1.215 | 1.509 | 3.154 |
Thread=1000use 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)
}