C++ cout printing slowly
Asked Answered
G

8

8

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?

Gamba answered 15/11, 2009 at 1:28 Comment(4)
I tried it on the Linux computer again, and cout and rcout seemed to be the same speed, but I know cout was much slower than printf in my other app so I'm thinking it might be because it was multithreaded? Then I tried it on my Vista comp and cout took about 375 ms while rcout took about 100 ms. On the Windows 7 comp cout took 850 ms and rcout took about 70 ms.Alyworth
<< endl? cout doesn't automatically flush data. It's possible you are running into Windows buffering the data differently than it does for printf. Also try cerr instead of cout and see if it makes a difference: if it does flushing is definitely the problem.Pony
cerr performed the same as cout, also doing a flush() after the cout does not helpAlyworth
It looks like Visual Studio is to blame for the slow cout, but I did have that Linux app that was printing slowly with cout and I switched it to printf and that fixed it. In that app I was using really simple couts, mostly just something like cout << buffer;. My guess is because there were 8 threads using cout, can anyone confirm this problem?Alyworth
E
13

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 :)

Empirin answered 15/11, 2009 at 1:53 Comment(4)
This is not correct; cout is not always faster than printf by any means. See my post for details.Mcmanus
I corrected my answer. But, my experiments on both Windows/Linux give always consistency. cout is slower than printf. I also counted # of executed instruction. Yes, cout needed more thatn printf. In Linux, 20% more instructions were needed for cout.Empirin
answer chosen for "Okay, cout in MSVS just sucks :)", you're right, that is the problemAlyworth
Now, we got the answer from Microsoft Connect- "this is an unfortunate consequence of how our C and C++ Standard Library implementations are designed". See connect.microsoft.com/VisualStudio/feedback/details/642876/…Incorporeity
M
9

I would suggest you try this same test on a different computer. I don't have a good answer for why this might be happening; all I can say is I have never noticed a speed difference between cout and printf. I also tested your code using gcc 4.3.2 on Linux and there was no difference whatsoever.

That being said, you can't easily replace cout with your own implementation. The fact is, cout is an instance of std::ostream which has a lot of functionality built into it which is necessary for interoperability with other classes that overload the iostream operators.

Edit:

Anyone that says printf is always faster than std::cout is simply wrong. I just ran the test code posted by minjang, with gcc 4.3.2 and the -O2 flag on a 64-bit AMD Athlon X2, and cout was actually faster.

I got the following results:

printf: 00:00:12.024
cout:   00:00:04.144

Is cout always faster than printf? Probably not. Especially not with older implementations. But on newer implementations iostreams are likely to be faster than stdio because instead of parsing a format string at runtime, the compiler knows at compile time what functions it needs to call in order to convert integers/floats/objects to strings.

But more importantly, the speed of printf versus cout depends on the implementation, and so the problem described by the OP is not easily explicable.

Mcmanus answered 15/11, 2009 at 1:42 Comment(4)
I also tested on Linux with icc -O3 on Xeon machine. Measured by time and put > /dev/null. In whatever case, cout requires more instructions to be completed. But, differences are small. For example, cout 0.311 vs printf 0.218. But, I absolutely agree it depends on implementation. I edited my answer.Empirin
@Empirin I think the test might be more meaningfull if you don't send stdout to dev/nullAlyworth
@Ramonster, printf still faster. Some details: compiled by g++ w/ -O3. cout took 4.9 secs, but printf took 4.5 secs. Not a big difference though. But, # of executed instructions are 775M for cout, 589M for printf. Actually, 200M differences in modern CPUs are quite small. Also, I need to assume that every instruction would take similar time (I know this isn't that reasonable). Anyway, in my experimentation, printf was faster on Linux and Windows.Empirin
class Rcout { public: template<class A> rcout &operator<<(A a) { stringstream ss; ss<<(a); fwrite(ss.str().c_str(), 1, ss.str().length(), stdout); return (*this); } }; Rcout rcout; int main() { rcout << "This is pretty good, thread safe too\n"; return 0; }Alyworth
L
4

Try call ios::sync_with_stdio(false); before using std::cout/cin, unless of course, you mix stdio and iostream in your program, which is a bad thing to do.

Ledezma answered 15/11, 2009 at 2:5 Comment(2)
that didn't seem to make a differenceAlyworth
Are you sure that you're using the "release/optimized" build? iostream tend to be much slower in debug mode because of the template code.Ledezma
M
1

Based on my experience in programming competitions, printf IS faster than cout.

I remember many times when my solution didn't make it before the Time limit just because of cin/cout, while printf/scanf did work.

Besides that, it seems normal (at least for me) that cout is slower than printf, because it does more operations.

Minaminabe answered 15/11, 2009 at 1:52 Comment(1)
It should never be that much slower, to the extent described by the OP.Mcmanus
P
0

Try using some endls or flushes as they will flush cout's buffer, in case the OS is caching your program's output for whatever reason. But, as Charles says, there's no good explanation for this behavior, so if that doesn't help then it's likely a problem specific to your machine.

Proposition answered 15/11, 2009 at 1:44 Comment(1)
I have tried using endl and flush(), they don't seem to make a difference. I timed the printing and got 842 ms for cout and 63 ms for my rcoutAlyworth
K
0

You should try to write all your data to an ostringstream first, and then use cout on the ostringstream's str(). I am on 64-bit Windows 7 and Test1 was already significantly faster than Test2 (your mileage may vary). Using an ostringstream to build a single string first and then using cout on that further decreased Test1's execution time by a factor of about 3 to 4. Be sure to #include <sstream>.

I.e., replace

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

with:

void Test1()
{
    ostringstream oss;
    oss
        << "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;
    cout << oss.str();
}

I suspect ostringstream makes this so much faster as a result of not trying to write to the screen each time you call operator<< on cout. I've also noticed through experience that reducing the number of times you write to the screen (by writing more at once) increases performance (again, your mileage may vary).

E.g.,

void Foo1()
{
    for(int i = 0; i < 10000; ++i) {
        cout << "Foo1\n";
    }
}

void Foo2()
{
    std::string s;
    for(int i = 0; i < 10000; ++i) {
        s += "Foo2\n";
    }
    cout << s;
}

void Foo3()
{
    std::ostringstream oss;
    for(int i = 0; i < 10000; ++i) {
        oss << "Foo3\n";
    }
    cout << oss.str();
}

In my case, Foo1 took 1,092ms, Foo2 took 234ms, and Foo3 took 218ms. ostingstreams are your friend. Obviously Foo2 and Foo3 require (trivially) more memory. To compare this against a C-style function, try sprintf into a buffer and then write that buffer using fprintf and you should see still more efficiency over Test2 (though for me this only improved performance of Test2 by about 10% or so; cout and printf are indeed different beasts under the hood).

Compiler: MinGW64 (TDM and its bundled libraries).

Karlee answered 4/2, 2014 at 17:17 Comment(0)
C
0

Try using ios::sync_with_stdio(false);. Mention it before using std::cin/cout. It doesn't mix stdio or iostream but it synchronizes iostream standard streams with their corresponding standard c streams. for example - std::cin/wcin of iostream is synchronized with stdin of c stream

Canvasback answered 18/4, 2015 at 8:53 Comment(0)
K
-2

Here is hax that should make c++ streams as fast as c printf. I never tested it but I believe it works.

ios_base::sync_with_stdio(0);
Katzenjammer answered 15/11, 2009 at 2:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.