假设我有以下Rust代码:
use indicatif::ProgressBar;
fn main() {
let limit = 100_000_000;
let pb = ProgressBar::new(limit);
for i in 0..limit {
pb.inc(1);
}
pb.finish();
}
执行此代码需要数十秒。
类似地,当我想显示大量循环的进度条,每个循环花费的时间很短时,似乎indicatif更新了每个循环终端上的进度条,开销变得很大。
有没有办法减少这种开销?例如,每50毫秒更新一次进度条?
(我知道我可以通过使用std::time::{Duration, Instant}
来实现,但我想知道更简单和可读的解决方案,如果它存在的话。
2条答案
按热度按时间7gcisfzg1#
indicatif
实现了自己的过滤机制。但是你的问题不是写,即使我们删除了所有的写,你的代码仍然很慢。问题在于过滤器本身。为了过滤(每毫秒10次),它在每次调用
inc()
时构造一个Instant
。建造它是缓慢的。有比
Instant::now()
更快的方法来获取当前时间,但它们也更复杂。也许,最好的方法是每N次迭代才调用inc()
。ngynwnxp2#
每隔50 ms更新一次进度条,而不在每次迭代中调用
Instant::now
,这是可能的,但要比你想象的困难得多:请注意,这比直接更新更快,但不是数量级更快。至少在Linux上,
Instant::now
相当便宜。原子商店更便宜,但不是免费的。