Перейти к содержимому

Ios base c что это

  • автор:

Класс ios_base

Класс описывает функции хранилища и члена, общие для входных и выходных потоков, которые не зависят от параметров шаблона. (Шаблон класса basic_ios описывает, что является общим и зависит от параметров шаблона.)

Объект класса ios_base хранит сведения о форматировании, состоящие из следующих элементов:

  • Форматирование флагов в объекте типа fmtflags .
  • Маска исключения в объекте типа iostate .
  • Ширина поля в объекте типа int .
  • Точность отображения в объекте типа int .
  • locale Объект в объекте типа locale .
  • Два расширяемых массива с элементами типа long и void указателя.

Объект класса ios_base также хранит сведения о состоянии потока в объекте типа iostate и стек обратного вызова.

Участники

Конструкторы

Имя Описание
ios_base Создает объект ios_base .

Определения типов

Имя Описание
event_callback Описывает функцию, переданную register_call в .
fmtflags Константы для определения внешнего вида выходных данных.
iostate Определяет константы, описывающие состояние потока.
openmode Описывает процесс взаимодействия с потоком.
seekdir Задает начальную точку для операций смещения.

Перечисления

Имя Описание
event Задает типы событий.

Константы

Имя Описание
adjustfield Битовая маска, определенная как internal right | left | .
app Задает поиск до конца потока перед каждой вставкой.
ate Задает поиск до конца потока при первом создании его управляющего объекта.
badbit Регистрирует потерю целостности буфера потока.
basefield Битовая маска, определенная как dec oct | hex | .
beg Задает поиск относительно начала последовательности.
binary Указывает, что файл должен быть считан как двоичный, а не текстовый поток.
boolalpha Задает вставку или извлечение объектов типа bool в качестве имен (таких как true и false ), а не числовых значений.
cur Задает поиск относительно текущей позиции в последовательности.
dec Задает вставку или извлечение целочисленных значений в десятичном формате.
end Задает поиск относительно конца последовательности.
eofbit Регистрирует конец файла при извлечении из потока.
failbit Регистрирует сбой при извлечении допустимого поля из потока.
fixed Задает вставку значений с плавающей запятой в формате с фиксированной запятой (без поля экспоненты).
floatfield Битовая маска, определенная как fixed | scientific
goodbit Очищает все биты состояния.
hex Задает вставку или извлечение целочисленных значений в шестнадцатеричном формате.
in Задает извлечение из потока.
internal Выполняет заполнение по ширине поля, вставляя символы заполнения в точке внутри созданного числового поля.
left Задает выравнивание по левому краю.
oct Задает вставку или извлечение целочисленных значений в восьмеричном формате.
out Задает вставку в поток.
right Задает выравнивание по правому краю.
scientific Задает вставку значений с плавающей запятой в экспоненциальном формате (с полем экспоненты).
showbase Задает вставку префикса, отображающего базу созданного целочисленного поля.
showpoint Задает безусловную вставку десятичной запятой в созданное поле с плавающей запятой.
showpos Задает вставку знака плюс в созданное неотрицательное числовое поле.
skipws Задает пропуск начальных пробелов перед определенными извлечениями.
trunc Задает удаление содержимого существующего файла при создании его управляющего объекта.
unitbuf Обеспечивает запись выходных данных на диск после каждой вставки.
uppercase Задает вставку эквивалентных прописных букв для букв нижнего регистра в определенных вставках.

Функции

Имя Описание
failure Класс-член служит базовым классом для всех исключений, создаваемых функцией-членом , ясной в шаблоне basic_ios класса.
flags Задает или возвращает текущие параметры флага.
getloc Возвращает сохраненный locale объект.
imbue Изменяет языковой стандарт.
Init Создает стандартные iostream объекты при создании.
iword Присваивает значение, сохраняемое в виде iword .
precision Задает количество цифр для отображения числа с плавающей запятой.
pword Присваивает значение, сохраняемое в виде pword .
register_callback Задает функцию обратного вызова.
setf Задает указанные флаги.
sync_with_stdio Гарантирует, что iostream и операции библиотеки времени выполнения C выполняются в том порядке, в который они отображаются в исходном коде.
unsetf Отключает указанные флаги.
width Задает длину потока вывода.
xalloc Указывает, что переменная должна быть частью потока.

Операторы

Имя Описание
operator= Оператор присваивания для объектов ios_base .

Требования

Заголовок.

Пространство имен std :

event

Задает типы событий.

enum event < erase_event, imbue_event, copyfmt_event>; 

Замечания

Тип — это перечислимый тип, описывающий объект, который может хранить событие обратного вызова, используемое в качестве аргумента для функции, зарегистрированной в register_callback . Различные значения события:

  • copyfmt_event , чтобы определить обратный вызов, который происходит ближе к концу вызова copyfmt , непосредственно перед копированием маски исключения.
  • erase_event , чтобы определить обратный вызов, который происходит в начале вызова или в начале вызова copyfmt деструктора. *this
  • imbue_event , чтобы определить обратный вызов, который происходит в конце вызова imbue , непосредственно перед возвращением функции.

Пример

event_callback

Описывает функцию, переданную register_call в .

typedef void (__cdecl *event_callback)( event _E, ios_base& _Base, int _I); 

Параметры

_Base
Поток, в котором был вызов события.

_I
Определенное пользователем число.

Замечания

Тип описывает указатель на функцию, в которую можно зарегистрировать register_callback . Функции этого типа не должны вызывать исключение.

Пример

Пример register_call использования event_callback .

failure

Класс failure определяет базовый класс для типов всех объектов, вызываемых как исключения, с помощью функций в библиотеке iostreams , для отчетов об ошибках, обнаруженных во время операций буфера потока.

namespace std < class failure : public system_error < public: explicit failure( const string& _Message, const error_code& _Code = io_errc::stream); explicit failure( const char* str, const error_code& _Code = io_errc::stream); >; > 

Замечания

Значение, возвращаемое what() , — это копия _Message , возможно, дополненная тестом на основе _Code . Если _Code значение по умолчанию не указано, значение make_error_code(io_errc::stream) по умолчанию .

Пример

// ios_base_failure.cpp // compile with: /EHsc #include #include int main ( ) < using namespace std; fstream file; file.exceptions(ios::failbit); try < file.open( "rm.txt", ios_base::in ); // Opens nonexistent file for reading >catch( ios_base::failure f ) < cout > 
Caught an exception: ios_base::failbit set 

flags

Задает или возвращает текущие параметры флага.

fmtflags flags() const; fmtflags flags(fmtflags fmtfl); 

Параметры

fmtfl
Новое значение fmtflags .

Возвращаемое значение

Предыдущее или текущее значение fmtflags .

Замечания

Первая функция-член возвращает сохраненные флажки формата. Вторая функция-член сохраняет fmtfl во флажках формата и возвращает свое ранее сохраненное значение.

Пример

// ios_base_flags.cpp // compile with: /EHsc #include #include int main ( )
513 16896 

fmtflags

Константы для определения внешнего вида выходных данных.

class ios_base < public: typedef implementation-defined-bitmask-type fmtflags; static const fmtflags boolalpha; static const fmtflags dec; static const fmtflags fixed; static const fmtflags hex; static const fmtflags internal; static const fmtflags left; static const fmtflags oct; static const fmtflags right; static const fmtflags scientific; static const fmtflags showbase; static const fmtflags showpoint; static const fmtflags showpos; static const fmtflags skipws; static const fmtflags unitbuf; static const fmtflags uppercase; static const fmtflags adjustfield; static const fmtflags basefield; static const fmtflags floatfield; // . >; 

Замечания

Поддерживает манипуляторы в ios .

Тип — это тип битовой маски, описывающий объект, который может хранить флаги формата. Ниже перечислены значения различных флагов (элементы).

  • dec , чтобы вставить или извлечь целочисленные значения в десятичном формате.
  • hex , чтобы вставить или извлечь целочисленные значения в шестнадцатеричном формате.
  • oct , чтобы вставить или извлечь целочисленные значения в восьмеричном формате.
  • showbase , чтобы вставить префикс, отображающий базу созданного целочисленного поля.
  • internal , чтобы выполнить заполнение по ширине поля, вставляя символы заполнения в точке внутри созданного числового поля. (Сведения о настройке ширины поля см. в разделе setw ).
  • left , чтобы выполнить заполнение по ширине поля, вставляя символы заполнения в конец созданного числового поля (выравнивание по левому краю).
  • right , чтобы выполнить заполнение по ширине поля, вставляя символы заполнения в начало созданного числового поля (выравнивание по правому краю).
  • boolalpha , чтобы вставить или извлечь объекты типа bool , например имена (такие как true и false ), а не числовые значения.
  • fixed , чтобы вставить значения с плавающей запятой в формате с фиксированной запятой (без поля экспоненты).
  • scientific , чтобы вставить значения с плавающей запятой в экспоненциальном формате (с полем экспоненты).
  • showpoint , чтобы выполнить безусловную вставку десятичной запятой в созданное поле с плавающей запятой.
  • showpos , чтобы вставить знак плюс в созданное неотрицательное числовое поле.
  • skipws , чтобы пропустить начальные пробелы перед определенными извлечениями.
  • unitbuf , чтобы записывать выходные данные на диск после каждой вставки.
  • uppercase , чтобы вставить эквивалентные прописные буквы для букв нижнего регистра в определенных вставках.

Кроме того, ниже приведено несколько полезных значений:

  • adjustfield , битовая маска, определенная как internal | left | right
  • basefield , определенный как dec | hex | oct
  • floatfield , определенный как fixed | scientific

Примеры функций, изменяющих флаги формата, см. в разделе .

getloc

Возвращает сохраненный locale объект.

locale getloc() const; 

Возвращаемое значение

Сохраненный locale объект.

Пример

// ios_base_getlock.cpp // compile with: /EHsc #include int main( )

imbue

Изменяет языковой стандарт.

locale imbue(const locale& _Loc); 

Параметры

_Loc
Новое значение языкового стандарта.

Возвращаемое значение

Предыдущий языковой стандарт.

Замечания

Функция-член хранится _Loc в объекте locale , а затем сообщает о событии обратного вызова и imbue_event . Она возвращает предыдущее сохраненное значение.

Пример

Init

Создает стандартные iostream объекты при создании.

class Init < >; 

Замечания

Вложенный класс описывает объект, строительство которого гарантирует правильность построения стандартных iostream объектов, даже до выполнения конструктора для произвольного статического объекта.

ios_base

Создает объект ios_base .

ios_base(); 

Замечания

(Защищенный) конструктор ничего не делает. Последующий вызов basic_ios:: init должен инициализировать объект, прежде чем он может быть безопасно уничтожен. Таким образом, единственным безопасным использованием для класса ios_base является базовый класс для шаблона basic_ios класса.

iostate

Тип констант, описывающих состояние потока.

class ios_base < public: typedef implementation-defined-bitmask-type iostate; static const iostate badbit; static const iostate eofbit; static const iostate failbit; static const iostate goodbit; // . >; 

Замечания

Тип — это тип битовой маски, описывающий объект, который может хранить данные о состоянии потока. Ниже перечислены значения различных флагов (элементы).

  • badbit регистрирует потерю целостности буфера потока.
  • eofbit регистрирует конец файла при извлечении из потока.
  • failbit регистрирует ошибку извлечения корректного поля из потока.

Кроме того, полезным является значение goodbit , где не устанавливаются никакие из упомянутых ранее бит ( goodbit гарантированно ноль).

iword

Присваивает значение, сохраняемое в виде iword .

long& iword(int idx); 

Параметры

idx
Индекс значения для сохранения как iword .

Замечания

Функция-член возвращает ссылку на идентификатор элемента расширяемого массива с элементами типа long . Все элементы эффективно присутствуют и изначально хранят нулевое значение. Возвращаемая ссылка недопустима после следующего вызова iword объекта, после изменения объекта вызовом basic_ios:: copyfmt или после уничтожения объекта.

Если idx для элемента нет отрицательного значения или если уникальное хранилище недоступно, функция вызывает setstate (badbit) и возвращает ссылку, которая может не быть уникальной.

Чтобы получить уникальный индекс, для использования во всех объектах типа ios_base , вызовите xalloc .

Пример

Пример xalloc использования iword .

openmode

Описывает процесс взаимодействия с потоком.

class ios_base < public: typedef implementation-defined-bitmask-type openmode; static const openmode in; static const openmode out; static const openmode ate; static const openmode app; static const openmode trunc; static const openmode binary; // . >; 

Замечания

Режим открытия для нескольких iostream объектов. Значения флага:

Константа Действие
app Поиск конца потока перед каждой записью
ate Поиск конца потока сразу после открытия
binary Открыть в двоичном режиме. (См fopen . описание двоичного режима.)
in Открыть для чтения
out Открытие для написания
trunc Удаление содержимого файла после открытия

Пример

// ios_base_openmode.cpp // compile with: /EHsc #include #include int main ( )

operator=

Оператор присваивания для объектов ios_base .

ios_base& operator=(const ios_base& right); 

Параметры

right
Объект типа ios_base .

Возвращаемое значение

Объект, которому выполняется присваивание.

Замечания

Оператор копирует сохраненные сведения о форматировании, создавая новую копию для любых расширяемых массивов. Затем оно возвращает значение *this . Стек обратного вызова не копируется.

Этот оператор используется только классами, производными от ios_base .

precision

Задает количество цифр для отображения числа с плавающей запятой.

streamsize precision() const; streamsize precision(streamsize _Prec); 

Параметры

_Prec
Количество значащих цифр при отображении, или количество цифр после десятичной запятой в фиксированной нотации.

Возвращаемое значение

Первая функция-член возвращает сохраненное количество цифр для отображения. Вторая функция-член сохраняет _Prec в качестве количества цифр для отображения и возвращает свое ранее сохраненное значение.

Замечания

Числа с плавающей запятой отображаются в фиксированной нотации с fixed .

Пример

// ios_base_precision.cpp // compile with: /EHsc #include int main( ) < using namespace std; float i = 31.31234F; cout.precision( 3 ); cout 
31.3 31.312 

pword

Присваивает значение, сохраняемое в виде pword .

void *& pword(int index); 

Параметры

index
Индекс значения для сохранения как pword .

Замечания

Функция-член возвращает ссылку на индекс элемента расширяемого массива с элементами указателя типа void . Все элементы эффективно присутствуют и изначально хранят нулевой указатель. Возвращаемая ссылка недопустима после следующего вызова pword объекта, после изменения объекта вызовом basic_ios:: copyfmt или после уничтожения объекта.

Если индекс отрицательный, или если уникальное хранилище недоступно для элемента, функция вызывает setstate (badbit) и возвращает ссылку, которая может не быть уникальной.

Чтобы получить уникальный индекс, для использования во всех объектах типа ios_base , вызовите xalloc .

Пример

См. xalloc с примером использования pword .

register_callback

Задает функцию обратного вызова.

void register_callback( event_callback pfn, int idx); 

Параметры

pfn
Указатель на функцию обратного вызова.

idx
Определенное пользователем число.

Замечания

Функция-член отправляет пару в сохраненный стек обратных вызовов стека обратных вызовов. Когда сообщается событие обратного вызова, функции вызываются в обратном порядке реестра выражением (*pfn)(ev, *this, idx) .

Пример

// ios_base_register_callback.cpp // compile with: /EHsc #include #include using namespace std; void callback1( ios_base::event e, ios_base& stream, int arg ) < cout ; > void callback2( ios_base::event e, ios_base& stream, int arg ) < cout ; > int main( ) < // Make sure the imbue will not throw an exception // assert( setlocale( LC_ALL, "german" )!=NULL ); cout.register_callback( callback1, 0 ); cin.register_callback( callback2, 0 ); try < // If no exception because the locale's not found, // generate an imbue_event on callback1 cout.imbue(locale("german")); >catch(. ) < cout // This will // (1) erase_event on callback1 // (2) copyfmt_event on callback2 cout.copyfmt(cin); // We get two erase events from callback2 at the end because // both cin and cout have callback2 registered when cin and cout // are destroyed at the end of program. > 
in callback1 an imbue event in callback1 an erase event in callback2 an copyfmt event in callback2 an erase event in callback2 an erase event 

seekdir

Задает начальную точку для операций смещения.

namespace std < class ios_base < public: typedef implementation-defined-enumerated-type seekdir; static const seekdir beg; static const seekdir cur; static const seekdir end; // . >; > 

Замечания

Тип — это перечислимый тип, описывающий объект, который может хранить режим поиска, используемый в качестве аргумента для функций-членов нескольких iostream классов. Ниже перечислены значения различных флагов.

  • beg , чтобы искать (изменить текущую позицию чтения или записи) относительно начала последовательности (массив, поток или файл).
  • cur , чтобы искать относительно текущей позиции в последовательности.
  • end , чтобы искать относительно конца последовательности.

Пример

// ios_base_seekdir.cpp // compile with: /EHsc #include #include int main ( )

setf

Задает указанные флаги.

fmtflags setf( fmtflags _Mask ); fmtflags setf( fmtflags _Mask, fmtflags _Unset ); 

Параметры

_Mask
Флажки, которые нужно включить.

_Unset
Флаги для отключения.

Возвращаемое значение

Предыдущие флаги форматирования

Замечания

Первая функция-член эффективно вызывает flags(_Mask | _Flags) (задает выбранные биты), а затем возвращает предыдущие флаги формата. Вторая функция-член фактически вызывает flags(_Mask & fmtfl, flags & ~_Mask) (замените выбранные биты под маской), а затем возвращает предыдущие флаги формата.

Пример

// ios_base_setf.cpp // compile with: /EHsc #include int main( )

sync_with_stdio

Гарантирует, что iostream и операции библиотеки времени выполнения C выполняются в том порядке, в который они отображаются в исходном коде.

static bool sync_with_stdio( bool _Sync = true ); 

Параметры

_Sync
Синхронизированы stdio ли все потоки.

Возвращаемое значение

Предыдущий параметр для этой функции.

Замечания

Функция статического члена сохраняет stdio флаг синхронизации, который изначально true . Если true этот флаг обеспечивает правильную синхронизацию операций с тем же файлом между iostreams функциями и функциями, определенными в стандартной библиотеке C++. В противном случае синхронизация может быть гарантирована или не гарантируется, но производительность может быть улучшена. Функция сохраняет _Sync в флаге stdio синхронизации и возвращает предыдущее сохраненное значение. Ее можно вызывать надежно только перед выполнением любых операций в стандартных потоках.

unsetf

Отключает указанные флаги.

void unsetf( fmtflags _Mask ); 

Параметры

_Mask
Флаги, которые требуется отключить.

Замечания

Функция-член эффективно вызывает flags(~_Mask & flags) (очистить выбранные биты).

Пример

См ios_base::setf . пример использования unsetf .

width

Задает длину потока вывода.

streamsize width( ) const; streamsize width( streamsize _Wide ); 

Параметры

_Wide
Нужный размер выходного потока.

Возвращаемое значение

Текущий параметр ширины.

Замечания

Первая функция-член возвращает ширину сохраненного поля. Вторая функция-член хранится _Wide в ширине поля и возвращает предыдущее сохраненное значение.

Пример

// ios_base_width.cpp // compile with: /EHsc #include int main( )
20 0 

xalloc

Указывает, что переменная является частью потока.

static int xalloc( ); 

Возвращаемое значение

Функция статического члена возвращает сохраненное статическое значение, которое увеличивается при каждом вызове.

Замечания

Возвращаемое значение можно использовать в качестве уникального аргумента индекса при вызове функций-членов iword или pword .

Пример

// ios_base_xalloc.cpp // compile with: /EHsc // Lets you store user-defined information. // iword, jword, xalloc #include int main( )
11 13 testing 

std::ios_base:: openmode

static constexpr openmode binary = /* implementation defined */ ;
static constexpr openmode in = /* implementation defined */ ;
static constexpr openmode out = /* implementation defined */ ;
static constexpr openmode trunc = /* implementation defined */ ;

static constexpr openmode ate = /* implementation defined */ ;

static constexpr openmode noreplace = /* implementation defined */ ;

Specifies available file open flags. It is a BitmaskType , the following constants are defined:

Constant Explanation
app seek to the end of stream before each write
binary open in binary mode
in open for reading
out open for writing
trunc discard the contents of the stream when opening
ate seek to the end of stream immediately after open
noreplace (C++23) open in exclusive mode

[edit] Example

Run this code

#include #include #include int main()  const char* fname = "unique_name.txt"; // write to a temporary stream object std::fstream(fname, std::ios::out 

std::ios_base::failure

Унаследовано от std::system_error

Member functions

Унаследовано от std::runtime_error

Унаследовано от std::exception

Member functions

Notes

  1. Теперь применяется спецификация негенерирующих исключений gloabally across the standard library , поэтому деструкторы стандартных классов library не объявляются с помощью throw() или noexcept .

Example

#include #include int main() < std::ifstream f("doesn't exist"); try < f.exceptions(f.failbit); > catch (const std::ios_base::failure& e) < std::cout "Caught an ios_base::failure.\n" "Explanatory string: " what() '\n' "Error code: " code() '\n'; > >
Caught an ios_base::failure. Explanatory string: ios_base::clear: unspecified iostream_category error Error code: iostream:1

Defect reports

DR Applied to Поведение в опубликованном виде Correct behavior
LWG 48 C++98 перегрузка конструктора (1) инициализировала базовый класс std::exception
с msg , но базовый класс не имеет соответствующего конструктора
corresponding
description removed
LWG 331 C++98 std::ios_base::failure объявил деструктор без throw(). удалил объявление деструктора

Ios base c что это

rohitrao835589 → memes of the day

_ _asm__ → Most annoying person on CF in 2023

Vladosiya → Codeforces Round 903 (Div. 3) Разбор

cloud_eve → Elementary Number Theory

MikeMirzayanov → Polygon: AI-Powered Automatic Tips

Blinov_Artemii → Bullying on Codeforces

maomao90 → Editorial for Hello 2024

Palestinian_Dream → Extracting Mathematical Ideas Behind The Problems

changingmong100 → Title: "A Mother's Love in Codeforces"

MikeMirzayanov → Codeforces Single Account Policy: zh0ukangyang is Removed from the Rating

I_HATE_CONSTRUCTIVES. → IZhO 2024 day 1 discussion

Victor_Luis123 → Is Dijkstra's overrated.

maomao90 → Hello 2024

atcoder_official → AtCoder Beginner Contest 335 (Sponsored by Mynavi) Announcement

Некропост

salt_n_ice → CSES Longest Flight Route TLE in one test case

Некропост

box → On the Min25 sieve and extensions / SPOJ ASSIEVE

maomao90 → I am top 1 contributor. AMA!

VivaciousAubergine → Wow! You received a rating of -501 in the CodeTON round. Share it!

whatthemomooofun1729 → codeforces login issue

mohammed_orkhan → I wnat to be EXPERT!!

uchicha_itachi → What does plagiarism actually include?

ATSTNG → Does Polygon automaticly send statements and tutorials of all problems into AI service?

Zhtluo → Is ICPC ECNA 2023 problem C straight-up wrong?

Pepe.Chess → What are some nice to attend programming camps

D_coder22 → Uncertainty in Python Time of Execution

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

Снова про ввод/вывод в C++

Автор andreyv, 11 лет назад ,

Хочу продолжить тему скорости ввода/вывода в C++, которую когда-то начал товарищ freopen. freopen сравнивал производительность двух способов ввода/вывода в C++: унаследованной от C библиотеки stdio ( ) и более новой библиотеки iostreams ( /…). Однако в этих тестах не было учтено, что iostreams можно значительно ускорить, включив некоторые оптимизации. Об их существовании уже неоднократно упоминалось на Codeforces (раз, два, три). Сейчас я написал софт, который сравнивает производительность stdio и iostreams на стандартном вводе/выводе с учётом этого.

UPD1: Добавлена информация про _CRT_DISABLE_PERFCRIT_LOCKS .
UPD2: Для полноты картины добавлены вызовы printf() / scanf() на строках.

Что это за оптимизации?

Первая состоит в том, что в начале программы, перед каким-либо вводом/выводом, можно вставить строчку

ios_base::sync_with_stdio(false);

Эта команда отключает синхронизацию iostreams с stdio (описание). По умолчанию она включена, то есть, iostreams и stdio можно использовать вместе на одном и том же потоке, перемежая их вызовы. После отключения синхронизации так делать больше нельзя, однако за счёт этого iostreams может работать быстрее.

Вторая оптимизация заключается в том, что для cin можно выключить привязку к cout :

cin.tie(NULL);

По умолчанию cin привязан к cout , что означает, что перед каждой операцией над cin сначала сбрасывается буфер cout (описание). Отключение этой функции опять-таки позволяет iostreams работать быстрее. С этой оптимизацией надо быть внимательным в интерактивных задачах: либо не использовать её, либо не забывать явный flush .

Отмечу ещё, что на производительность iostreams негативно влияет частое использование endl , поскольку endl не только выводит символ новой строки, но и сбрасывает буфер потока (описание). Вместо endl можно просто выводить '\n' или "\n" .

Какие тесты включены в программу?

Я постарался сымитировать наиболее типичные ситуации, возникающие при решении задач.

  • Ввод/вывод int с помощью stdio, iostreams и, для сравнения, самопальных функций
  • Ввод/вывод double
  • Посимвольный ввод/вывод
  • Ввод/вывод строк: как с char * , так и с std::string

Какие тесты не включены в программу?

  • long long — полагаю, результат будет коррелировать с int
  • Преобразование int и запись результата в собственный буфер достаточно большого размера, а затем прямой вывод буфера с помощью fwrite() / cout.write() (и аналогичное решение для ввода)
  • Экзотический способ посимвольного ввода/вывода: cin.rdbuf()->sgetc() и cout.rdbuf()->sputc()
  • Какие-либо манипуляции с размером буфера потоков (похоже, что в GCC iostreams для стандартных потоков игнорирует пользовательские установки насчёт этого). Это направление ещё можно исследовать потом.

Как это запустить у себя?

Надо скомпилировать программу, не забыв включить оптимизацию ( -O2 /Release), и запустить её с тем же рабочим каталогом, где она и находится. Если при запуске в Windows появляется сообщение Access denied, то может помочь запуск программы с повышенными правами. Программе потребуется пара сотен мегабайтов свободного места в каталоге для временных файлов.

Дополнительные замечания

  • Почему нужно для каждого теста создавать новый процесс?

Из-за ios_base::sync_with_stdio(false) , который препятствует поочерёдному тестированию stdio и iostreams, а также (теоретически) мешает использовать freopen() , чтобы перенаправлять cin / cout .

  • Зачем удалять файл от предыдущего запуска перед каждым тестом?

Чтобы все запуски были в равных условиях. Хотя, это несколько спорный вопрос. Может, лучше не удалять, а переписывать?

  • Почему время измеряет запускаемый, а не запускающий процесс?

Чтобы исключить время запуска/завершения процесса.

  • Почему бы вместо clock() не использовать более точные вызовы, например, getrusage() ?

Это можно. Но сначала мне надо понять, как это делать в Windows 🙂

Результаты

Запускал на компьютере с Pentium 4, так что время может показаться несколько большим.

  • Для Visual C++ 2010: http://pastie.org/4680309
int, printf 9.45 9.48 9.44 int, cout 22.03 22.01 22.21 int, custom/out 11.17 11.06 11.20 int, scanf 5.04 4.77 4.82 int, cin 20.26 20.16 20.16 int, custom/in 10.25 10.25 10.25 double, printf 19.23 18.98 18.95 double, cout 37.49 37.52 37.44 double, scanf 12.11 11.75 11.73 double, cin 26.88 26.57 26.57 char, putchar 13.29 13.76 13.48 char, cout 23.52 24.15 23.41 char, getchar 12.87 12.82 12.74 char, cin 16.13 16.22 16.50 char *, printf 6.88 6.74 6.57 char *, puts 3.95 3.82 3.95 char *, cout 6.36 6.32 6.43 string, cout 6.40 6.40 6.61 char *, scanf 6.16 6.10 6.13 char *, gets 3.98 3.96 3.96 char *, cin 8.72 8.91 8.85 string, getline 11.70 11.47 11.53

Здесь всё очевидно: stdio значительно превосходит по скорости iostreams. Примечательно, что на int printf() / scanf() быстрее даже самописных функций (однако см. дополнение ниже). Ввод/вывод строк с помощью puts() / gets() быстрее, чем с помощью printf() / scanf() — ну, это и понятно. Запись std::string занимает столько же, сколько и запись char * , а вот чтение в std::string медленнее — наверняка из-за необходимости динамически выделять память.

  • Для MinGW (GCC 4.7.0): http://pastie.org/4680314
int, printf 9.72 9.61 9.61 int, cout 6.08 6.05 6.10 int, custom/out 2.73 2.75 2.76 int, scanf 5.01 5.01 5.01 int, cin 3.99 4.04 4.04 int, custom/in 0.86 0.86 0.87 double, printf 22.51 22.40 22.42 double, cout 110.98 111.77 111.01 double, scanf 12.18 12.20 12.17 double, cin 118.87 118.84 118.87 char, putchar 1.67 1.65 1.64 char, cout 3.93 3.87 3.85 char, getchar 0.78 0.80 0.80 char, cin 3.29 3.31 3.29 char *, printf 5.55 5.47 5.49 char *, puts 5.37 5.32 5.41 char *, cout 8.72 8.72 8.78 string, cout 8.74 8.71 9.06 char *, scanf 7.07 7.04 7.02 char *, gets 3.84 3.79 3.77 char *, cin 5.30 5.38 5.35 string, getline 14.15 14.12 14.16

А здесь всё уже не так однозначно. Неожиданно оказывается, что iostreams на 20-30% быстрее stdio на int . Правда, самописные функции значительно обгоняют и то, и то. С double наоборот: iostreams заметно тормозит. Посимвольный ввод/вывод с putchar() / getchar() работает в 2-3 раза быстрее cout / cin . Ввод/вывод строк отличается не так сильно, но stdio и тут быстрее. На строках puts() / gets() также быстрее, чем printf() / scanf() . std::string , как и в предыдущем случае, работает одинаково с char * на выводе, однако медленнее на вводе.

Какие делать выводы и что использовать, пусть каждый решает сам. В комментариях приветствуется флейм конструктивное обсуждение.

Дополнение

В Visual C++ есть способ значительно ускорить базовые операции с потоками stdio, отключив блокировку потоков для функций getchar() , putchar() и некоторых других. Для этого надо перед всеми #include вставить строчку

#define _CRT_DISABLE_PERFCRIT_LOCKS

(описание). Это сработает только при выполнении следующих дополнительных условий:

  • Программа статически компонуется со стандартной библиотекой ( /MT ; на Codeforces, похоже, это так)
  • Программа включает , но не включает ни , ни какой-либо файл из библиотеки iostreams ( /…)

Вместо всей этой магии можно также просто использовать _putchar_nolock() / _getchar_nolock() вместо putchar() / getchar() . В Linux тоже есть похожие функции: ссылка.

С этой оптимизацией посимвольный ввод/вывод ускоряется в восемь-девять (!) раз, а вместе с ним и вручную написанные функции ввода/вывода int :

int, custom/out 1.70 1.70 1.72 int, custom/in 1.28 1.26 1.28 char, putchar 1.72 1.62 1.61 char, getchar 1.36 1.34 1.36

В MinGW такое поведение включено по умолчанию и не имеет вышеописанных ограничений.

Теги

c++, ввод-вывод, производительность

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *