#rayon #progress-bar #display #computation #iterator #items #processed

rayon-progress

允许 Rayon 并行迭代器显示进度条的适配器

1 个稳定版本

1.0.0 2024 年 2 月 10 日

#22 in #rayon

MIT 许可证

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