Для действительно большого файла, такого как 1 ГБ, wc -l
бывает медленно. У нас есть более быстрый способ подсчета количества новых строк для конкретного файла?
command-line
wc
прости
источник
источник
0x0A
отсутствия, ввод / вывод, несомненно, является узким местом.wc
что у вас слишком много накладных расходов, вы можете попробовать реализовать свои собственныеforeach byte in file: if byte == '\n': linecount++
. Реализованный в C или ассемблере, я не думаю, что он станет быстрее, за исключением, возможно, пространства ядра в ОСРВ с наивысшим приоритетом (или даже для этого использует прерывание - вы просто не можете ничего сделать с системой). .. хорошо, я отвлекся ;-))time wc -l some_movie.avi
некэшированный файл, в результате чего5172672 some_movie.avi -- real 0m57.768s -- user 0m0.255s -- sys 0m0.863s
. Что в основном доказывает правильность @thrig, I / O разрушает вашу производительность в этом случае.time wc -l some_large_file_smaller_than_cache
дважды подряд и посмотреть, как быстро выполняется вторая операция, а затемtime wc -l some_large_file_larger_than_cache
посмотреть, как не меняется время между запусками. Для файла размером ~ 280 МБ время идет от 1,7 до 0,2 секунд, но для файла объемом 2 ГБ - 14 секунд оба раза./usr/bin/time wc -l <file>
говорит? Какое у вас оборудование? Это быстрее, если вы запускаете команду несколько раз? Нам действительно нужно больше информации;)Ответы:
Вы можете попробовать написать на C:
Сохранить, например,
wcl.c
скомпилировать, например, с помощьюgcc wcl.c -O2 -o wcl
и запустить сЭто находит переводы строк в 1 Гб файла в моей системе примерно за 370 мс (повторные запуски ). (Увеличение размеров буфера немного увеличивает время, которое следует ожидать - BUFSIZ должен быть близок к оптимальному). Это очень сравнимо с ~ 380 мс, которые я получаю
wc -l
.Mmaping дает мне лучшее время около 280 мс , но оно, конечно, имеет ограничение, ограниченное реальными файлами (без FIFOS, без ввода с терминала и т. Д.):
Я создал свой тестовый файл с:
и добавил несколько тестовых новых строк с:
и шестнадцатеричный редактор.
источник
for
цикла OpenMP ), так что некоторый прогресс может быть достигнут, пока один поток останавливается в ожидании ввода. Но, с другой стороны, это может затруднить планирование ввода / вывода, поэтому все, что я могу порекомендовать, это попробовать и измерить!read()
Версия может извлечь выгоду из упреждающего чтения.Вы можете улучшить решение, предлагаемое @pskocik, уменьшив количество звонков до
read
. Существует много вызовов для чтенияBUFSIZ
фрагментов из файла объемом 1 ГБ. Обычный подход к этому заключается в увеличении размера буфера:BUFSIZ
это 8192. С оригинальной программой это 120 тысяч операций чтения. Вы, вероятно, можете позволить себе входной буфер 1 Мб, чтобы уменьшить его в 100 раз.При тестировании различных подходов вы можете иметь в виду, что некоторые системы (например, Linux) используют большую часть неиспользуемой памяти вашей машины в качестве дискового кэша. Некоторое время назад (почти 20 лет назад, упомянутое в подлых FAQ ) я был озадачен неожиданно хорошими результатами (не очень хорошего) алгоритма подкачки, который я разработал для обработки условий нехватки памяти в текстовом редакторе. Мне объяснили, что он работает быстро, потому что программа работает из буферов памяти, используемых для чтения файла, и что только если файл будет перечитан или записан, будет разница в скорости.
То же самое относится и к
mmap
(в другом случае, все еще в моем списке дел для включения в FAQ, разработчик сообщил о очень хороших результатах в сценарии, где дисковый кеш был реальной причиной улучшения). Разработка эталонных тестов требует времени и усилий, чтобы проанализировать причины хорошей (или плохой) производительности.Дальнейшее чтение:
источник
dd
использованием буферов 1 МБ медленнее, чем 8 КБ. Значение по умолчанию для wc 8 КБ выбрано довольно хорошо, оно будет близко к оптимальному для широкого диапазона систем.