#progress #log #logging #free-memory

dsi-progress-logger

DSSI实用工具库中的ProgressLogger类的Rust移植。

10个版本

0.2.4 2024年3月25日
0.2.3 2024年3月18日
0.2.2 2023年11月2日
0.1.4 2023年10月30日
0.1.1 2023年5月21日

#329 in 调试

Download history 192/week @ 2024-04-08 134/week @ 2024-04-15 140/week @ 2024-04-22 166/week @ 2024-04-29 160/week @ 2024-05-06 79/week @ 2024-05-13 136/week @ 2024-05-20 128/week @ 2024-05-27 163/week @ 2024-06-03 111/week @ 2024-06-10 190/week @ 2024-06-17 92/week @ 2024-06-24 70/week @ 2024-07-01 74/week @ 2024-07-08 86/week @ 2024-07-15 142/week @ 2024-07-22

每月389次下载
3 个代码包中使用(通过 sux

Apache-2.0 OR LGPL-2.1-or-later

35KB
513

DSI 进度记录器

downloads dependents GitHub CI license Latest version Documentation

一个可调整的进度记录器,用于记录长时间运行活动的进度信息。

它是从DSI Utilities中移植的Java类 it.unimi.dsi.util.ProgressLogger,日志记录基于标准的 log 包,在 info 级别。

存在一个 ProgressLog 接口和一个默认实现 ProgressLogger

要记录活动的进度,您调用 start。然后,每次您想要标记进度时,调用 update,它将增加项目计数器,如果自上次日志记录以来经过足够的时间,它将记录进度信息。 light_update 仅在更新的倍数为 LIGHT_UPDATE_MASK + 1 时执行时间检查;当活动的成本极低,与时间检查(调用 Instant::now() 本身相当)时应该使用。

可以在任何时间调用几个设置器来定制记录器(例如,item_namelog_intervalexpected_updates等)。设置器接收并返回对记录器的可变引用,因此您必须首先将记录器分配给一个变量,然后可以在变量上以流畅的风格链式调用设置器。这种方法的缺点是必须将记录器分配给一个变量,但优点是无需重新分配持有记录器的变量就可以调用任何设置器。后面还将介绍一个progress_logger! 宏。

还可以通过调用 display_memory 在每个日志间隔记录已使用和空闲内存。内存是通过 sysinfo 包从系统数据中读取的,并将在每个日志间隔更新(请注意,这会略微减慢日志记录过程)。

在任何时候,显示进度记录器都会给出直至现在的时序信息。然而,由于无法从 Display::fmt 实现更新内存信息,您应在显示记录器之前调用 refresh

当活动完成时,您可以调用 stop,这会固定最终时间,并可能再次显示记录器。调用 done 将停止记录器,打印 Completed. 并显示最终统计数据。

完成进度记录器的运行后,可以再次调用 start 来测量另一项活动。

调用进度记录器的典型顺序如下

# fn main() -> Result<(), Box<dyn std::error::Error>> {
use dsi_progress_logger::prelude::*;

stderrlog::new().verbosity(2).init()?;

let mut pl = ProgressLogger::default();
pl.item_name("pumpkin");
pl.start("Smashing pumpkins...");
for _ in 0..100 {
   // do something on each pumpkin
   pl.update();
}
pl.done();
#     Ok(())
# }

progress_logger 宏会为您创建进度记录器并设置其 log_target 为 [std::module_path!()],这通常是您想要的。您也可以使用键值语法调用任何设置器

# fn main() -> Result<(), Box<dyn std::error::Error>> {
use dsi_progress_logger::prelude::*;

stderrlog::new().verbosity(2).init()?;

let mut pl = progress_logger!(item_name="pumpkin");
pl.start("Smashing pumpkins...");
for _ in 0..100 {
   // do something on each pumpkin
   pl.update();
}
pl.done();
#     Ok(())
# }

进度记录器也可以用作便捷的计时器

# fn main() -> Result<(), Box<dyn std::error::Error>> {
use dsi_progress_logger::prelude::*;

stderrlog::new().verbosity(2).init()?;

let mut pl = progress_logger!(item_name="pumpkin");
pl.start("Smashing pumpkins...");
for _ in 0..100 {
   // do something on each pumpkin
}
pl.done_with_count(100);
#     Ok(())
# }

此进度记录器将显示内存使用信息

# fn main() -> Result<(), Box<dyn std::error::Error>> {
use dsi_progress_logger::prelude::*;

stderrlog::new().verbosity(2).init()?;

let mut pl = progress_logger!(display_memory=true);
#     Ok(())
# }

可选日志

此crate通过实现ProgressLog,为Option<ProgressLog>提供可选日志记录功能,作为一个空操作。因此,你可以将一个名为pl的参数传递给函数,该参数是一个impl ProgressLog实现,具有以下行为:

  • 如果你传递了一个ProgressLogger,进度记录器将被使用,而不进行任何检查;
  • 如果你传递Option::<ProgressLogger>::None,则不会执行日志记录,实际上编译器应该会完全优化掉日志记录代码;
  • 如果你传递一个Option<ProgressLogger>,日志记录将根据变体进行,并且每次调用pl时都会进行运行时检查。

有一个info方法,可以用来将信息以info级别记录到记录器中。使用info的优点是日志记录将根据记录器的类型是可选的。

克隆

clone方法将返回一个具有相同设置但所有计数器都已重置的记录器。当你想要配置一个记录器然后使用其配置为其他记录器时,这非常有用。

请注意,此方法是ProgressLog的一部分:否则,由于孤儿规则,我们无法为Option<ProgressLog>实现它。

致谢

本软件部分由欧盟-NGEU资助的NRRP MUR计划下的SERICS项目(PE00000014)支持。

依赖关系

~3–4.5MB
~85K SLoC