Search code examples
performancerustprogress-bar

Reducing overhead of indicatif ProgressBar in Rust


Let's say I have a following Rust code:

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();
}

It takes tens of seconds to execute this code.

Similarly, when I want to show a progress bar for a large number of loop with a small time taken for each loop, it seems indicatif updates the progress bar written on the terminal every loop and the overhead becomes significant.

Is there a way to reduce this overhead? For example, updating the progress bar every 50 milliseconds?

(I know I can do it from using std::time::{Duration, Instant} but I want to know simpler & readable solution if it exists.)


Solution

  • indicatif implements its own filtering mechanism. But your problem is not the writes, even if we remove all of them, your code is still slow. Your problem is the filter itself.

    To filter (10 ticks per millisecond) it constructs an Instant on every call to inc(). And constructing it is slow.

    There are faster ways to get the current time than Instant::now(), but they're also more complicated. Probably, the best path forward is to call inc() only every N iterations.