EgoRusMarch
@EgoRusMarch
C++ Developer

Посимвольный i/o vs i/o в строку (буфер)?

Услышал такое мнение:
Посимвольный ввод-вывод работает очень медленно. Это особенно заметно на больших файлах, поэтому, если есть возможность, надо считать как можно больший кусок в память и потом уже проводить с ним манипуляции.

Сами стандартные потоки ввода-вывода имеют внутри себя свой буфер. И по идее все должно быть весьма неплохо. Но когда начинаешь ставить опыты, обнаруживается, что между идеей и реальностью есть некоторые расхождения.
Сам вызов fgetc - это один PUSH в стек при подготовке вызова (если реализация использует передачу параметров через стек). Для fgets это будет уже 3 PUSH-а, но при этом за раз можно считать целую строку, т. е. в расчете на один символ выходит, в среднем, гораздо меньше времени.
Вообще, если интересно, попробуйте сделать программы для подсчета кол-ва символов в файле через fgetc, fgets и read с размером буфера в несколько Мб :) А потом измерьте время, за которое оно сосчитает количество символов в образе DVD или BR диска.

Насколько это верно? Правда ли, что посимвольный ввод/вывод лучше избегать?
  • Вопрос задан
  • 115 просмотров
Решения вопроса 3
@res2001
Developer, ex-admin
Это верно!
Особенно заметно, когда нужна обработка больших файлов.
Избегать или нет - зависит от ситуации. Если скорость не важна, а файл не большой, то можно не заморачиваться.

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

На больших файлах вместо собственной буферизации можно использовать механизм "файлов проецируемых в память", предоставляемый ОС.
Ответ написан
Комментировать
@Mercury13
Программист на «си с крестами» и не только
Очень-очень верно! Даже на чём-то типа istringstream виртуальный вызов занимает довольно много времени, и ОЧЕНЬ желательна буферизация своими силами.
Подтверждаю, приходилось писать код скоростного разбора XML.
Ответ написан
Комментировать
CityCat4
@CityCat4
Внимание! Изменился адрес почты!
Это абсолютно верно. Посимвольного ввода-вывода (getchar()/putchar(), getc()/putc(), fgetc()/fputc()) стоит избегать как только можно. Если файл небольшой (и даже не очень большой) - его проще всего считать в память и уже в памяти его как угодно крутить-вертеть.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы