16

In C++, which would be faster if repeated, say, 5000 times:

cout << "text!" << endl;

or

my_text_file << "text!" << endl;

(writing to a file vs. cout-ing to the console)

Edit:

I ask because when writing to the console, you see all the text being printed which seems like it would slow down the loop. In a file, you arn't seeing the text being printed, which seems as if it would take less time.

Just tested it:

Console: > 2000 ms using endl and \n

File: 40 ms with endl and 4 ms with \n

Christian
  • 573
  • 3
  • 6
  • 15
  • You can't make sure what is the standart output being redirected for, but disk access (like writing on a file) is _much_ slower than ram access (printing console). – JulioC Jun 14 '11 at 03:46
  • 5
    @Julio: Have you tested this in a real environment ever? Printing to console is usually much slower than writing to disk, it is not just leaving the characters in a buffer, but the buffer is limited, and the contents of that buffer need to be moved to the video card (a real text terminal) or drawn on the screen (a graphical terminal) with enough data, the intermediate buffer fills, and the writer process stalls waiting for the output to be drawn... Before making this type of *strong* statements on performance, actually measure, in a real environment with enough data you will see that yourself. – David Rodríguez - dribeas Jun 14 '11 at 07:39
  • @David Rodríguez - dribeas +1: really interesting, thanks – JulioC Jun 14 '11 at 16:20

4 Answers4

18

Writing to a file would be much faster. This is especially true since you are flushing the buffer after every line with endl.

On a side note, you could speed the printing significantly by doing repeating cout << "text!\n"; 5000 times, then flushing the buffer using flush().

Dominic Gurto
  • 4,025
  • 2
  • 18
  • 16
  • 7
    This will probably sound dumb... What exactly is the buffer? – Christian Jun 14 '11 at 03:51
  • 2
    When you output something to a stream (such as cout), whatever you send is stored in a buffer before it is actually put there (flushed). It happens every now and then, and when the program's execution completes correctly. However, using flush or endl explicitly flushes it. This just ensures that things get printed when we want them to. – Dominic Gurto Jun 14 '11 at 03:58
2

It's not that much faster...

A test of 1 million couts with endl (clear buffer):

Results:

console cout time: 2.87001
file cout time: 2.33776

Code:

class Timer
{
        struct timespec startTime, endTime;
        double sec;
public:
        void start();
        void stop();
        double getSec();
};

void Timer::start()
{
        clock_gettime(CLOCK_MONOTONIC, &startTime);
}
void Timer::stop()
{
        clock_gettime(CLOCK_MONOTONIC, &endTime);
        sec = (endTime.tv_sec - startTime.tv_sec);
        sec += (endTime.tv_nsec - startTime.tv_nsec) / 1000000000.0;
}
double Timer::getSec()
{
        return sec;
}


int main(){
        int ntests = 1000000;
        Timer t1 = Timer(), t2 = Timer();

        t1.start();
        for(int c=0;c<ntests;c++)
        {
                cout << "0" << endl;
        }
        t1.stop();

        ofstream out("out.txt");
        streambuf *coutbuf = cout.rdbuf();
        cout.rdbuf(out.rdbuf());
        t2.start();
        for(int c=0;c<ntests;c++)
        {
                cout << "0" << endl;
        }
        t2.stop();
        cout.rdbuf(coutbuf);

        cout << "console cout time: " << t1.getSec() << endl;
        cout << "file cout time: " << t2.getSec() << endl;
}

Build and run:

g++ test.cpp -o test -lrt && ./test && rm out.txt
Jason
  • 1,974
  • 24
  • 19
2

In addition to console I/O generally being relatively slow, the default configuration of the standard streams cout and cin has some issues that will greatly slow performance if not corrected.

The reason is that the standard mandates that, by default, cout and cin from the C++ iostream library should work alongside stdout and stdin from the C stdio library in the expected way.

This basically means that cout and cin can't do any buffering at all in its internal streambufs and basically forwards all I/O operations over to the C library.

If you want to do anything resembling high performance I/O with the standard streams, you need to turn off this synchronization with

std::ios_base::sync_with_stdio(false);

before doing any I/O.

1

Writing the same amount of data, with the same buffer size to the console will most definitely be faster than writing to a file.

You can speed up your write speed (both for console output, and file output) by not writing out the buffer with every line (i.e.- don't use std::endl after every line, as it both adds an endline to the stream, and writes the buffer). Instead use "\n" unless you need to ensure the buffer is output for some reason.

MarkD
  • 4,864
  • 5
  • 36
  • 67
  • Unless you're outputting over a very slow serial link. – genpfault Jun 14 '11 at 03:46
  • 1
    Including all that printing and scrolling that would be visible while printing to the console? In a text file, you wouldn't be seeing the text being written. – Christian Jun 14 '11 at 03:46
  • Writing to the console is faster, but if the write operation is all that's performed, then a program writing to a file will probably finish first. – jswolf19 Jun 14 '11 at 03:47
  • @vorbis5: you don't necessarily see it in a terminal either. When I worked for a financial data provider, the server logs were written too fast to tail in the Solaris xterm of the day but no problem in rxvt precisely because it was smart enough to limit redraws per second and let data pass through invisibly, but the last N lines were still there in the buffer if you bothered to scroll back. Still, a fixed-length in-memory buffer's less stress to maintain than growing a file on magnetic disk. – Tony Delroy Jun 14 '11 at 04:28