Daniel
Daniel

Reputation: 2726

Looking for a more efficient way to generate/print a "progress bar" in C++

I am working on some grid generation code, during which I really want to see where I am, so I download a piece of progress bar code from internet and then inserted it into my code, something like:

std::string bar;

for(int i = 0; i < 50; i++)
{
    if( i < (percent/2))
    {
        bar.replace(i,1,"=");
    }
    else if( i == (percent/2))
    {
        bar.replace(i,1,">");
    }
    else
    {
        bar.replace(i,1," ");
    }
}

std::cout<< "\r" "[" << bar << "] ";
std::cout.width( 3 );
std::cout<< percent << "%     "
    << " ieration: " << iterationCycle << std::flush;

This is very straightforward. However, it GREATLY slows down the whole process, note percent=iterI/nIter.

I am really get annoyed with this, I am wondering if there is any smarter and more efficient way to print a progress bar to the screen.

Thanks a million.

Upvotes: 1

Views: 678

Answers (3)

Joost
Joost

Reputation: 4134

Firstly you could consider only updating it on every 100 or 1000 iterations. Secondly, I don't think the division is the bottleneck, but much rather the string operations and the outputting itself.

I guess the only significant improvement would be to just output less often.

Oh and just for good measure - an efficient way to only execute the code every, say, 1024 iterations, would be not to see if 1024 is a divisor using the modulo operations, but rather using bitwise calls. Something along the lines of

if (iterationCycle & 1024) {

would work. You'd be computing the bitwise AND of iterationCycle and 1024, only returning positive for every time the bit on the 10th position would be a 1. These kind of operations are done extremely fast, as your CPU has specific hardware for them.

Upvotes: 4

Dmitry Ledentsov
Dmitry Ledentsov

Reputation: 3660

You should really check "efficiency", but what would work almost the same ist boost.progress:

#include <boost/progress.hpp>
...
boost::progress_display pd(50);
for (int i=0; i<=60; i++) {
 ++pd;
}

and as Joost already answered, output less often

Upvotes: 0

Kerrek SB
Kerrek SB

Reputation: 477040

You might be overthinking this. I would just output a single character every however-many cycles of your main application code. Run some tests to see how many (hundreds? millions?), but you shouldn't print more than say once a second. Then just do:

std::fputc('*', stdout);
std::fflush(stdout);

Upvotes: 0

Related Questions