Обычно пользователи потоковых классов не должны связываться со сбросом потока, если требуется максимальная производительность: потоки внутренне очищают свой буфер, когда он заполнен.Это на самом деле более эффективно, чем ожидание, пока все выходные данные не будут готовы, особенно для больших файлов: буферизованные данные записываются, пока они все еще находятся в памяти.Если вы создаете огромный буфер и записываете его только один раз, система виртуальной памяти поместит части данных на диск, но не файл.Его нужно будет прочитать с диска и записать снова.
Главное в отношении std::endl
состоит в том, что люди злоупотребляют этим концом строки, что приводит к сбросу буфера, и они не знают о последствиях для производительности.Намерение std::endl
состоит в том, чтобы люди могли контролировать файлы в разумные моменты времени.Чтобы это было эффективным, им нужно знать, что они делают.К сожалению, было слишком много людей, неосведомленных о том, что делает std::endl
, которые рекламировали его использование в качестве окончания строки, так что оно используется во многих местах, где это явно неправильно.
Тем не менее, ниже приведен рядвещи, которые вы могли бы попытаться улучшить производительность.Я предполагаю, что вам нужен форматированный вывод (который вам не даст использование std::ofstream::write()
).
- Очевидно, что не используйте
std::endl
, если вам не нужно.Если код записи уже существует и использует std::endl
во многих местах, некоторые из которых, возможно, находятся вне вашего контроля, вы можете использовать буфер потока фильтрации, который использует свой внутренний буфер разумного размера и который не перенаправляет вызовы на его sync()
Функция в основной буфер потока.Хотя для этого требуется дополнительная копия, это лучше, чем некоторые ложные сбросы, поскольку это на несколько порядков дороже. - Хотя это не должно влиять на
std::ofstream
s, вызывая std::ios_base::sync_with_stdio(false)
, используемый дляпроизводительность на некоторых реализациях.Возможно, вы захотите взглянуть на использование другой реализации IOstream, если это даст эффект, потому что, вероятно, с производительностью не все в порядке. - Убедитесь, что вы используете
std::locale
, std::codecvt<...>
которого возвращает true
при вызове его always_noconv()
.Это легко проверить с помощью std::use_facet<std::codecvt<char, char, stdd::mbstate_t> >(out.get_loc()).always_noconv()
.Вы можете использовать std::locale("C")
, чтобы получить std::locale
, для которого это должно быть верно. - Некоторые реализации локали используют очень неэффективные реализации своих числовых аспектов и даже, если они достаточно хороши, реализация по умолчаниюиз
std::num_put<char>
фасета все еще может делать то, что вам действительно не нужно.Особенно, если ваше числовое форматирование достаточно простое, то есть вы не меняете флаги форматирования, вы не заменяете отображение символов (т.е. вы не используете забавный std::ctype<char>
фасет) и т. Д., Может быть разумно использоватьпользовательский std::num_put<char>
фасет: довольно просто создать быструю, но простую функцию форматирования для целочисленных типов и хорошую функцию форматирования для чисел с плавающей запятой, которая не использует snprintf()
внутри.
Некоторыелюди предложили использовать файлы с отображением в памяти, но это разумно, если размер целевого файла известен заранее.Если это так, то это отличный способ улучшить производительность, иначе это не стоит беспокоиться.Обратите внимание, что вы можете использовать форматирование потока для файлов с отображенной памятью (или, в более общем случае, с любым интерфейсом вывода), создав пользовательский std::streambuf
, который использует интерфейс отображения памяти.Я обнаружил, что отображение памяти иногда эффективно при использовании их с std::istream
s.Во многих случаях различия не имеют большого значения.
Давным-давно я написал свою собственную реализацию IOStreams и locales, которая не страдает от некоторых проблем производительности, упомянутых выше (она доступна в мой сайт , но он немного устаревший, и я почти 10 лет не трогал его).Есть много вещей, которые могут быть улучшены по сравнению с этой реализацией, но у меня нет современной реализации, которую я был бы готов опубликовать где-нибудь.Надеюсь, скоро - то, о чем я думаю уже почти 10 лет ...