Блог пользователя promix17

Автор promix17, 10 лет назад, По-русски

Как лучше организовать вывод результата на С++? Когда я использую обычный вывод, то могу получить превышение TL на задачах с сложностью O(n):

cout << smth << endl;

Если же использовать printf, то решение проходит, однако я не хочу использовать printf.

Я так понимаю, что, по умолчанию, стандартный вывод записывается на диск всякий раз при получении символа новой строки. Верно ли это? Вопрос такой: какую функцию надо вызвать, чтобы изменить буферизацию стандартного выходного потока с построчной на блочную? Нужно решение как для Windowws, так и для Linux.

  • Проголосовать: нравится
  • -8
  • Проголосовать: не нравится

»
10 лет назад, # |
  Проголосовать: нравится +21 Проголосовать: не нравится
  1. не использовать endl, именно он каждый раз флашит(не дает буфееризироваться)
  2. использовать sync_With_stdio(false), чтобы не тратить время на синхронизацию с printf
»
10 лет назад, # |
Rev. 2   Проголосовать: нравится +5 Проголосовать: не нравится

Да, endl делает за собой flush потока. Избежать этого просто:

cout << smth << "\n";

P.S. Еще одна оптимизация, отрубаем синхронизация iostream с cstdio (нельзя будет на одном потоке оперировать и scanf, и cin, например):

ios_base::sync_with_stdio(0); // пишется в самом начале мейна
»
10 лет назад, # |
  Проголосовать: нравится +19 Проголосовать: не нравится

Несколько полезных ссылок на эту тему:

»
10 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Всё ровно надо будет учиться ими пользоваться рано или поздно, так-что почему-бы не учиться прямо сейчас. Так-что "Надо Федя, надо".

»
10 лет назад, # |
  Проголосовать: нравится +12 Проголосовать: не нравится

Три магические строчки:

#define endl '\n'
cin.sync_with_stdio(0);
cin.tie(0);
»
10 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Я так понимаю, что, по умолчанию, стандартный вывод записывается на диск всякий раз при получении символа новой строки. Верно ли это?

Нет, по умолчанию стандартный вывод полностью буферизован. Буфер сбрасывается тогда, когда он становится полным, или же явно вызывается операция сброса (как при cout << flush или cout << endl). Вместо endl надо использовать '\n'.

Исключение составляют случаи, когда стандартный вывод подключён к интерактивному терминалу (а не к файлу или вводу другой программы). Тогда он действительно буферизуется построчно, то есть, вывод символа перевода строки сбрасывает буфер.

Стоит отметить, что даже если сделать вывод небуферизованным, то это не будет ещё означать, что данные сразу записываются на диск, а только то, что данные сразу помещаются в системный буфер, который существует вне текущего процесса и которым управляет ядро операционной системы.