Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ cout printing slowly

I noticed if I print out a long string(char*) using cout it seems to print 1 character at a time to the screen in Windows 7, Vista, and Linux(using putty) using Visual C++ 2008 on Windows and G++ on Linux. Printf is so much faster I actually switched from cout to printf for most printing in a project of mine. This is confusing me because this question makes it seem like I'm the only one having this issue.

I even wrote a cout replacement that looks like it beats the pants off of cout on my comp -

class rcout
{
public:
    char buff[4096];
    unsigned int size;
    unsigned int length;

    rcout()
    {
        size = 4096;
        length = 0;
        buff[0] = '\0';
    }

    ~rcout()
    {
        printf("%s", buff);
    }

    rcout &operator<<(char *b)
    {
        strncpy(buff+length, b, size-length);
        unsigned int i = strlen(b);
        if(i+length >= size)
        {
            buff[size-1] = '\0';
            printf("%s", buff);
            b += (size-length) -1;
            length = 0;
            return (*this) << b;
        }
        else
            length += i;
        return (*this);
    }

    rcout &operator<<(int i)
    {
        char b[32];
        _itoa_s(i, b, 10);
        return (*this)<<b;
    }

    rcout &operator<<(float f)
    {
        char b[32];
        sprintf_s(b, 32, "%f", f);
        return (*this)<<b;
    }
};

int main()
{
    char buff[65536];
    memset(buff, 0, 65536);

    for(int i=0;i<3000;i++)
        buff[i] = rand()%26 + 'A';

    rcout() << buff << buff <<"\n---"<< 121 <<"---" << 1.21f <<"---\n";
    Sleep(1000);
    cout << "\n\nOk, now cout....\n\n";
    cout << buff << buff <<"\n---"<< 121 <<"---" << 1.21f <<"---\n";
    Sleep(1000);
    cout << "\n\nOk, now me again....\n\n";
    rcout() << buff << buff <<"\n---"<< 121 <<"---" << 1.21f <<"---\n";
    Sleep(1000);

    return 0;
}

Any ideas why cout is printing so slowly for me?

like image 580
Ramónster Avatar asked Nov 15 '09 01:11

Ramónster


1 Answers

NOTE: This experimental result is valid for MSVC. In some other implementation of library, the result will vary.

printf could be (much) faster than cout. Although printf parses the format string in runtime, it requires much less function calls and actually needs small number of instruction to do a same job, comparing to cout. Here is a summary of my experimentation:

The number of static instruction

In general, cout generates a lot of code than printf. Say that we have the following cout code to print out with some formats.

os << setw(width) << dec << "0x" << hex << addr << ": " << rtnname <<
  ": " << srccode << "(" << dec << lineno << ")" << endl;

On a VC++ compiler with optimizations, it generates around 188 bytes code. But, when you replace it printf-based code, only 42 bytes are required.

The number of dynamically executed instruction

The number of static instruction just tells the difference of static binary code. What is more important is the actual number of instruction that are dynamically executed in runtime. I also did a simple experimentation:

Test code:

int a = 1999;
char b = 'a';
unsigned int c = 4200000000;
long long int d = 987654321098765;
long long unsigned int e = 1234567890123456789;
float f = 3123.4578f;
double g = 3.141592654;

void Test1()
{
    cout 
        << "a:" << a << “\n”
        << "a:" << setfill('0') << setw(8) << a << “\n”
        << "b:" << b << “\n”
        << "c:" << c << “\n”
        << "d:" << d << “\n”
        << "e:" << e << “\n”
        << "f:" << setprecision(6) << f << “\n”
        << "g:" << setprecision(10) << g << endl;
}

void Test2()
{
    fprintf(stdout,
        "a:%d\n"
        "a:%08d\n"
        "b:%c\n"
        "c:%u\n"
        "d:%I64d\n"
        "e:%I64u\n"
        "f:%.2f\n"
        "g:%.9lf\n",
        a, a, b, c, d, e, f, g);
    fflush(stdout);
}

int main()
{
    DWORD A, B;
    DWORD start = GetTickCount();
    for (int i = 0; i < 10000; ++i)
        Test1();
    A = GetTickCount() - start;

    start = GetTickCount();
    for (int i = 0; i < 10000; ++i)
        Test2();
    B = GetTickCount() - start;
    
    cerr << A << endl;
    cerr << B << endl;
    return 0;
}

Here is the result of Test1 (cout):

  • # of executed instruction: 423,234,439
  • # of memory loads/stores: approx. 320,000 and 980,000
  • Elapsed time: 52 seconds

Then, what about printf? This is the result of Test2:

  • # of executed instruction: 164,800,800
  • # of memory loads/stores: approx. 70,000 and 180,000
  • Elapsed time: 13 seconds

In this machine and compiler, printf was much faster cout. In both number of executed instructions, and # of load/store (indicates # of cache misses) have 3~4 times differences.

I know this is an extreme case. Also, I should note that cout is much easier when you're handling 32/64-bit data and require 32/64-platform independence. There is always trade-off. I'm using cout when checking type is very tricky.

Okay, cout in MSVS just sucks :)

like image 193
minjang Avatar answered Sep 23 '22 01:09

minjang