1 个稳定版本
1.0.0 | 2024 年 2 月 10 日 |
---|
#22 in #rayon
14KB
190 代码行,不含注释
rayon_progress
Rayon 是一个强大的库,可以通过多线程使操作更快,但很少能假设这样的操作会立即完成。因此,当需要处理例如数百万个元素的迭代器时,显示进度条通常很有用,这样用户就可以知道他们大约需要等待多长时间。
此包为任何实现 ParallelIterator
的类型提供了一个薄的包装器,该包装器跟踪已处理的元素数量,并允许从另一个线程访问该值。
use rayon::prelude::*;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use std::thread::sleep;
use rayon_progress::ProgressAdaptor;
let it = ProgressAdaptor::new(0..1000); // the constructor calls into_par_iter()
// get a handle to the number of items processed
// calling `progress.get()` repeatedly will return increasing values as processing continues
let progress = it.items_processed();
// it.len() is available when the underlying iterator implements IndexedParallelIterator (e.g.
// Range, Vec etc.)
// in other cases your code will have to either display indefinite progress or make an educated guess
let total = it.len();
// example method of transferring the result back to the thread that asked for it.
// you could also use `tokio::sync::oneshot`, `std::sync::mpsc` etc., or simply have the progress bar
// happen in a separate thread that dies when it gets notified that processing is complete.
let result = Arc::new(Mutex::new(None::<u32>));
// note that we wrap the iterator in a `ProgressAdaptor` *before* chaining any processing steps
// this is important for the count to be accurate, especially if later processing steps return
// fewer items (e.g. filter())
rayon::spawn({
let result = result.clone();
move || {
let sum = it.map(|i| {
sleep(Duration::from_millis(10)); // simulate some nontrivial computation
i
})
.sum();
*result.lock().unwrap() = Some(sum);
}
});
while result.lock().unwrap().is_none() {
let percent = (progress.get() * 100) / total;
println!("Processing... {}% complete", percent);
}
if let Some(result) = result.lock().unwrap().take() {
println!("Done! Result was: {}", result);
};
依赖关系
~1.5MB
~25K SLoC