2013-11-14 2 views
7

Я помогал кому-то с вопросом о выходе на C, и я не смог ответить на этот, казалось бы, простой вопрос, на который я хотел использовать ответ (в моем ответе), то есть:Самый быстрый выход в файл в c и C++

Каков самый быстрый способ вывода в файл на C/C++?

Я проделал большую работу с генерацией простых чисел и математическим алгоритмом, используя C++ и Java, и это было самым большим удержанием для меня иногда - мне иногда нужно много перемещать в файл и быстро.

Простите меня, если на это был дан ответ, но я искал google и SO в течение некоторого времени безрезультатно.

Я не ожидаю, что кто-то сделает работу по бенчмаркингу, но есть несколько способов подать в файл, и я сомневаюсь, что знаю их всех.

Итак, подведем итог,

Какие способы есть для вывода в файл в C и C++?

И какой из них является более быстрыми?

Очевидно, перенаправление с консоли ужасно. Любое краткое сравнение printf, cout, fputc и т. Д. Поможет.

Edit:

Из комментариев,

Там отличный базовый тест соиЬ и Printf в: mixing cout and printf for faster output

Это отличный старт, но не самый лучший ответ на то, что Я прошу. Например, он не обрабатывает std :: ostreambuf_iterator <>, упомянутый в комментариях, если это возможно. Он также не обрабатывать fputc или упомянуть перенаправление консоли (как плохо по сравнению) (не то, что ему нужно)

Edit 2:

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

Временное хранилище полезно только здесь - вы не можете буферизировать гигабайты данных, которые я знаю ,

+1

Имейте yo попытался использовать std :: ostreambuf_iterator C++ <>? –

+0

Я не слышал об этом. Благодарю. Я должен попытаться написать несколько тестов бенчмаркинга со всеми методами, которые я могу найти через несколько дней. – Plasmarob

+0

Возможный дубликат [mix cout и printf для более быстрого вывода] (http://stackoverflow.com/questions/1924530/mixing-cout-and-printf-for-faster-output) – cubrr

ответ

1

cout на самом деле немного быстрее, чем printf, потому что это функция шаблона, поэтому сборка предварительно скомпилирована для используемого типа, хотя разница в скорости незначительна. Я думаю, что ваша настоящая бутылочная шея - это не вызов, который делает язык, а скорость записи на жестких дисках. Если вы действительно хотите пройти весь путь, вы можете создать многопоточное или сетевое решение, которое будет хранить данные в буфере, а затем медленно записывать данные на жесткий диск отдельно от обработки данных ,

+1

Я думал, что функции шаблона были немного медленнее из-за накладных расходов. – Plasmarob

+0

Разделение обработки на многопоточность - это гениальная идея. – Plasmarob

+2

Они занимают больше времени для компиляции, но после их компиляции это просто сборка. http://stackoverflow.com/questions/2442358/do-c-templates-make-programs-slow –

2

Насколько я знаю, самым большим узким местом было бы написать персонаж за раз (например, используя fputc). Это сравнивается с созданием буфера в памяти и сбрасыванием всей партии (с использованием fwrite). Опыт показал мне, что использование fputc и запись отдельных персонажей значительно медленнее.

Это, вероятно, связано с аппаратными факторами, а не с какой-либо одной функцией.

+0

Значит, вы замечаете, что лучше отправлять большие куски данных в файл? Например. отправляя пару десятков номеров/строк с потоком вместо одного? – Plasmarob

+1

В общем, писать более крупные куски лучше. Для каждого вызова на выход есть накладные расходы. Выполнение 20 вызовов для записи 1 символа на один вызов имеет 20-кратное накладные расходы, так как делает 1 вызов для записи 20 символов. –

+1

@Plasmarob Да. Мне пришлось загрузить файл размером 118 Мб. Я начал использовать fgetc, для загрузки потребовалось более 15 минут. Я изменил его, чтобы использовать fread, и это сократилось примерно до 5 минут. (Я знаю, что вы говорите о написании, а не читаете. Но та же идея применяется) –

1

Узкое место в производительности вывода - это форматирование символов.

Во встроенных системах я улучшил производительность, форматируя текст в буфер (массив символов), а затем отправляя весь буфер для вывода с использованием команд записи блоков, таких как cout.write или fwrite. Функция обхода форматирования и передачи данных почти прямо.

Вы можете столкнуться с буферизацией ОС по пути.

Узкое место не связано с процессом форматирования символов, но несколько вызовов функции.

Если текст является постоянным, не называйте отформатированные функции вывода, записать его прямой:

static const char Message[] = "Hello there\n"; 
cout.write(&Message[0], sizeof(Message) - 1); // -1 because the '\0' doesn't need to be written 
2

функции, такие как fwrite, fprintf и т.д., на самом деле делает write системный вызов. Единственная разница с write заключается в том, что эти функции используют буфер для уменьшения количества системных вызовов.

Так что, если мне нужно выбирать между fwrite, fprintf и write, я бы избежать fprintf, потому что это хорошо, но сложная функция, которая делает много вещей. Если мне действительно нужно что-то быстро, я бы полностью восполнил составную часть до минимально необходимого минимума. И между fwrite и write я бы выбрал fwrite, если мне нужно написать много небольших данных, иначе write может быть быстрее, потому что он не требует всей системы буферизации.

Смежные вопросы