前回の続き。mutexを使わないバージョンで書き直してみました。
mutex以外も見直して変更をしましたがスッキリ書けました。処理速度も書き直す前と比べてそれほど変わらないです。
tokioを使ったバージョンはこれで終わりにしたいと思います。
次はtokioに代わりasync-stdを使って書き直してみます。
Mean | Std.Dev. | Min | Median | Max | |
real | 3.183 | 0.166 | 3.086 | 3.16 | 4.303 |
user | 2.425 | 0.109 | 2.224 | 2.422 | 2.776 |
sys | 8.556 | 0.372 | 8.216 | 8.494 | 10.922 |
Mean | Std.Dev. | Min | Median | Max | |
real | 4.574 | 0.169 | 4.391 | 4.547 | 5.648 |
user | 5.88 | 0.182 | 5.584 | 5.866 | 6.665 |
sys | 11.047 | 0.358 | 10.447 | 11.033 | 13.08 |
Mean | Std.Dev. | Min | Median | Max | |
real | 4.504 | 0.314 | 4.258 | 4.46 | 6.557 |
user | 3.678 | 0.163 | 3.412 | 3.657 | 4.21 |
sys | 17.284 | 0.957 | 16.391 | 17.148 | 23.445 |
Mean | Std.Dev. | Min | Median | Max | |
real | 6.204 | 0.412 | 5.153 | 6.168 | 7.923 |
user | 9.201 | 0.245 | 8.747 | 9.172 | 9.887 |
sys | 23.854 | 2.22 | 16.862 | 23.86 | 30.093 |
use anyhow::Result; // 1.0.71 use clap::Parser; // 4.3.11 use tokio::fs; // 1.32.0 use tokio::task::JoinSet; #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] struct Args { /// target directory #[arg(short, long, default_value_t = String::from(".") )] dir: String, } #[tokio::main] async fn main() -> Result<()> { let args = Args::parse(); let dir_string = args.dir.to_string(); println!("{}", dir_string); let mut list_from_thd: Vec<String> = vec![dir_string]; // Like a do-while while !list_from_thd.is_empty() { let mut thds = JoinSet::new(); for item in list_from_thd { thds.spawn(get_dirs(item)); } let mut new_dir_list = Vec::<String>::new(); while let Some(Ok(Ok(mut dir))) = thds.join_next().await { new_dir_list.append(&mut dir); } list_from_thd = new_dir_list; } Ok(()) } async fn get_dirs(dir: String) -> Result<Vec<String>> { let mut entries = fs::read_dir(dir).await?; // Folder list let mut dirs = Vec::<String>::new(); let mut thds = JoinSet::new(); while let Some(entry) = entries.next_entry().await? { let metadata = entry.metadata().await?; let path = entry.path(); let path_2 = path.clone(); thds.spawn(async move { let path = path.display().to_string(); if metadata.is_dir() { println!("{}", path); return path; } String::with_capacity(0) }); thds.spawn(async move { let path = path_2; if let Ok(symlink) = fs::read_link(&path).await { if path.is_dir() { println!("{}@ -> {}", path.display(), symlink.display()); } } String::with_capacity(0) }); } while let Some(Ok(dir)) = thds.join_next().await { if !dir.is_empty() { dirs.push(dir); } } Ok(dirs) }