perf: Parallelverarbeitung wiederherstellen (2.4-2.9x Speedup)
rayon's par_iter() auf indexierten Collections bewahrt die Reihenfolge, daher war die Entfernung im vorherigen Commit unnötig. Mapping-Logik in Closure extrahiert um Code-Duplizierung zu vermeiden. Benchmark (dry-run, quiet): 5.050 Einträge: 48ms seq → 20ms par (2.4x) 20.050 Einträge: 186ms seq → 63ms par (2.9x) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ad44139e21
commit
b08ff38a49
1 changed files with 38 additions and 28 deletions
66
src/main.rs
66
src/main.rs
|
|
@ -11,6 +11,7 @@ use config::Config;
|
|||
use glob::Pattern;
|
||||
use indicatif::{ProgressBar, ProgressStyle};
|
||||
use log::{debug, error, info};
|
||||
use rayon::prelude::*;
|
||||
use sanitizer::{clean_filename, is_excluded, is_safe_rename, Sequence};
|
||||
use std::fs;
|
||||
use std::io::IsTerminal;
|
||||
|
|
@ -31,6 +32,9 @@ const DEFAULT_EXCLUDES: &[&str] = &[
|
|||
"__pycache__/**",
|
||||
];
|
||||
|
||||
// Schwellwert für parallele Verarbeitung (bei weniger Dateien lohnt sich der Overhead nicht)
|
||||
const PARALLEL_THRESHOLD: usize = 100;
|
||||
|
||||
/// Repräsentiert eine geplante Umbenennungsoperation
|
||||
#[derive(Debug)]
|
||||
struct RenameOperation {
|
||||
|
|
@ -161,39 +165,45 @@ fn main() -> Result<()> {
|
|||
None
|
||||
};
|
||||
|
||||
// Berechne Umbenennungen
|
||||
// Hinweis: Die Reihenfolge (tiefste zuerst) muss erhalten bleiben,
|
||||
// damit Parent-Verzeichnisse nicht vor ihren Kindern umbenannt werden.
|
||||
let rename_ops: Vec<RenameOperation> = entries
|
||||
.iter()
|
||||
.filter_map(|entry| {
|
||||
let old_path = entry.path();
|
||||
// Berechne Umbenennungen (parallel bei vielen Dateien, sequentiell bei wenigen)
|
||||
// Hinweis: rayon's par_iter() auf indexierten Collections bewahrt die Reihenfolge,
|
||||
// sodass die tiefenbasierte Sortierung erhalten bleibt.
|
||||
let map_entry = |entry: &walkdir::DirEntry| -> Option<RenameOperation> {
|
||||
let old_path = entry.path();
|
||||
|
||||
// Ebenentiefe 0 -> überspringen
|
||||
if entry.depth() == 0 && entry.file_type().is_dir() && !args.modify_root {
|
||||
return None;
|
||||
// Ebenentiefe 0 -> überspringen
|
||||
if entry.depth() == 0 && entry.file_type().is_dir() && !args.modify_root {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Special Files (Symlinks, Sockets, etc.) nur mit --special
|
||||
let file_type = entry.file_type();
|
||||
if !args.special && (!file_type.is_file() && !file_type.is_dir()) {
|
||||
if args.verbose && file_type.is_symlink() {
|
||||
debug!(
|
||||
"Überspringe Symlink: {} (nutze --special um Symlink-Namen zu bereinigen)",
|
||||
old_path.display()
|
||||
);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
// Special Files (Symlinks, Sockets, etc.) nur mit --special
|
||||
let file_type = entry.file_type();
|
||||
if !args.special && (!file_type.is_file() && !file_type.is_dir()) {
|
||||
if args.verbose && file_type.is_symlink() {
|
||||
debug!("Überspringe Symlink: {} (nutze --special um Symlink-Namen zu bereinigen)", old_path.display());
|
||||
}
|
||||
return None;
|
||||
}
|
||||
// Dateiname ermitteln und bereinigen
|
||||
let filename = old_path.file_name()?;
|
||||
let new_name = clean_filename(filename, &config, &sequence, false)?;
|
||||
let new_path = old_path.with_file_name(&new_name);
|
||||
|
||||
// Dateiname ermitteln und bereinigen
|
||||
let filename = old_path.file_name()?;
|
||||
let new_name = clean_filename(filename, &config, &sequence, false)?;
|
||||
let new_path = old_path.with_file_name(&new_name);
|
||||
|
||||
Some(RenameOperation {
|
||||
old_path: old_path.to_path_buf(),
|
||||
new_path,
|
||||
})
|
||||
Some(RenameOperation {
|
||||
old_path: old_path.to_path_buf(),
|
||||
new_path,
|
||||
})
|
||||
.collect();
|
||||
};
|
||||
|
||||
let rename_ops: Vec<RenameOperation> = if entries.len() >= PARALLEL_THRESHOLD {
|
||||
entries.par_iter().filter_map(map_entry).collect()
|
||||
} else {
|
||||
entries.iter().filter_map(map_entry).collect()
|
||||
};
|
||||
|
||||
// Statistiken
|
||||
let total_processed = entries.len();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue