前回の続き。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)
}