#progress #update #task #regular #system-clock #scheduling #long

nightly progress-observer

简单实用工具,用于在长时间运行的单线程任务上同步高效地调度定期的进度更新

12 个稳定版本

3.2.0 2024 年 3 月 20 日
3.1.0 2024 年 3 月 17 日
2.2.0 2024 年 3 月 10 日
1.1.0 2024 年 3 月 10 日

12#system-clock

MIT 许可协议

20KB
178 行代码(不包括注释)

简单实用工具,用于在长时间运行的单线程任务上同步高效地调度定期的进度更新。

根据上次打印输出所用的时间长度自动调整提供更新的间隔。

与在预定的时间间隔内检查系统时钟的简单实现相比,这种实现只在每个进度读取时精确检查一次系统时钟。然后,它观察自上次读取以来经过的时间,并使用该时间来估计下次应该再次观察时钟以进行下一次读取之前需要等待多少个滴答。因此,这种实现非常高效,同时仍能在期望的时间间隔内提供定期的更新。

如果单个步骤的执行时间过于混乱,那么进度更新可能会变得不可预测和不规则。然而,观察者的操作在很大程度上对执行时间的不规则性具有弹性。

use std::time::Duration;
use std::io::{stdout, Write};
use progress_observer::prelude::*;
use rand::prelude::*;

// compute pi by generating random points within a square, and checking if they fall within a circle

fn pi(total: u64, in_circle: u64) -> f64 {
    in_circle as f64 / total as f64 * 4.0
}

let mut rng = thread_rng();
let mut in_circle: u64 = 0;
let mut observer = Observer::new(Duration::from_secs_f64(0.5));
let n: u64 = 10_000_000;
for i in 1..n {
    let (x, y): (f64, f64) = rng.gen();
    if x * x + y * y <= 1.0 {
        in_circle += 1;
    }
    if observer.tick() {
        print!("\rpi = {}", pi(i, in_circle));
        stdout().flush().unwrap();
    }
}
println!("pi = {}", pi(n, in_circle))
use std::time::Duration;
use std::io::{stdout, Write};
use progress_observer::prelude::*;
use rand::prelude::*;

// use the observer as an iterator

fn pi(total: usize, in_circle: u64) -> f64 {
    in_circle as f64 / total as f64 * 4.0
}

let mut rng = thread_rng();
let mut in_circle: u64 = 0;
let n = 10_000_000;
for (i, should_print) in
    Observer::new(Duration::from_secs_f64(0.5))
    .take(n)
    .enumerate()
{
    let (x, y): (f64, f64) = rng.gen();
    if x * x + y * y <= 1.0 {
        in_circle += 1;
    }
    if should_print {
        print!("\rpi = {}", pi(i, in_circle));
        stdout().flush().unwrap();
    }
}
println!("pi = {}", pi(n, in_circle))

无运行时依赖