diff --git a/Cargo.lock b/Cargo.lock index 4969a62..eb13649 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -236,7 +236,7 @@ dependencies = [ [[package]] name = "l-s" -version = "0.3.1" +version = "0.3.2" dependencies = [ "anyhow", "clap", diff --git a/Cargo.toml b/Cargo.toml index 31b0761..10021d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "l-s" -version = "0.3.1" +version = "0.3.2" authors = ["licsber "] edition = "2021" diff --git a/src/meta/progress.rs b/src/meta/progress.rs index ac5ff37..4699a71 100644 --- a/src/meta/progress.rs +++ b/src/meta/progress.rs @@ -1,4 +1,5 @@ -use std::sync::{Arc, Mutex}; +use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::Arc; use std::time::Instant; use indicatif::{ProgressBar, ProgressStyle}; @@ -8,9 +9,10 @@ use crate::utils::friendly_size; /// 进度跟踪器,封装进度条和 IO 统计信息 pub struct ProgressTracker { progress_bar: Option, - bytes_read: Arc>, - iops: Arc>, + bytes_read: Arc, + iops: Arc, start_time: Instant, + last_update: Arc, } impl ProgressTracker { @@ -32,9 +34,10 @@ impl ProgressTracker { Self { progress_bar, - bytes_read: Arc::new(Mutex::new(0u64)), - iops: Arc::new(Mutex::new(0u64)), + bytes_read: Arc::new(AtomicU64::new(0)), + iops: Arc::new(AtomicU64::new(0)), start_time: Instant::now(), + last_update: Arc::new(AtomicU64::new(0)), } } @@ -42,7 +45,15 @@ impl ProgressTracker { pub fn finish_file(&self) { if let Some(pb) = &self.progress_bar { pb.inc(1); - self.update_message(); + // 每 10 个文件或每 0.5 秒更新一次消息,减少开销 + let files_processed = pb.position(); + let now = self.start_time.elapsed().as_millis() as u64; + let last_update = self.last_update.load(Ordering::Relaxed); + + if files_processed % 10 == 0 || now.saturating_sub(last_update) > 500 { + self.update_message(); + self.last_update.store(now, Ordering::Relaxed); + } } } @@ -50,8 +61,8 @@ impl ProgressTracker { fn update_message(&self) { if let Some(pb) = &self.progress_bar { let elapsed = self.start_time.elapsed().as_secs_f64(); - let total_bytes = *self.bytes_read.lock().unwrap(); - let total_ops = *self.iops.lock().unwrap(); + let total_bytes = self.bytes_read.load(Ordering::Relaxed); + let total_ops = self.iops.load(Ordering::Relaxed); if total_bytes > 0 && elapsed > 0.0 { let speed_bytes_per_sec = total_bytes as f64 / elapsed; @@ -73,7 +84,7 @@ impl ProgressTracker { pub fn bytes_callback(&self) -> impl FnMut(u64) { let bytes_read = self.bytes_read.clone(); move |bytes| { - *bytes_read.lock().unwrap() += bytes; + bytes_read.fetch_add(bytes, Ordering::Relaxed); } } @@ -81,7 +92,7 @@ impl ProgressTracker { pub fn iop_callback(&self) -> impl FnMut() { let iops = self.iops.clone(); move || { - *iops.lock().unwrap() += 1; + iops.fetch_add(1, Ordering::Relaxed); } } }