Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternating cin/cout is slow?

Tags:

c++

iostream

To start off, I am doing std::ios_base::sync_with_stdio(false). I have the following pieces of code, reading a million integers from a text file (<input.txt >output.txt):

int tests;
cin >> tests;
for (int i = 0; i < tests; ++i) {
  int number;
  cin >> number;
  cout << number << "\n";
}

and

int tests;
cin >> tests;
vector<int> numbers(tests);
for (int i = 0; i < tests; ++i) {
  cin >> numbers[i];
}
for (int i = 0; i < tests; ++i) {
  cout << numbers[i] << "\n";
}

Of course, in reality they do more than just printing the same numbers. The problem is, the first block takes about 4 times as long (6.2 seconds versus 1.8).

Rewriting the same code with printf/scanf takes 3 seconds i both cases. What is the reason behind this?

like image 789
riv Avatar asked Oct 19 '22 21:10

riv


1 Answers

See std::basic_ios::tie, in particular these parts:

A tied stream is an output stream which is synchronized with the sequence controlled by the stream buffer (rdbuf()), that is, flush() is called on the tied stream before any input/output operation on *this.

By default, the standard streams cin, cerr and clog are tied to cout. Similarly, their wide counterparts wcin, wcerr and wclog are tied to wcout.

The point is to make sure that, in a typical interactive program doing things like cout << "Enter something: "; cin >> something;, the prompt actually appears on the screen before the program waits for input.

But in your case, those extra flush() calls defeat any buffering the streams might do, thus hurting performance.

You can break the tie with cin.tie(nullptr);

like image 89
Igor Tandetnik Avatar answered Nov 11 '22 09:11

Igor Tandetnik