Как ускорить команду grep / awk?
Вы так уверены, что grep
или awk
является виновником вашей ощущаемой медлительности? Знаете ли вы о cut (1) или sed (1) ? Вы тестировали время для запуска wc (1) на ваших данных? Возможно, текстовый ввод-вывод отнимает много времени.
Пожалуйста, сравните несколько раз и используйте time (1) для сравнения вашей программы.
У меня есть высокопроизводительный рабочий стол Debian (с AMD 2970WX, 64 ГБ ОЗУ, системным диском на 1 ТБ SSD, многотерабайтными дисками данных SATA 7200 об / мин) и я просто запускаю wc
для файла размером 25 ГБ (некоторые *.tar.xz
архив) сидение на жестком диске занимает более 10 минут (измеряется с помощью time
), а wc
выполняет некоторую очень простую текстовую обработку, читая этот файл последовательно , поэтому должен работать быстрее чем grep
(но, к моему удивлению, нет!) или awk
на тех же данных:
wc /big/basile/backup.tar.xz 640.14s user 4.58s system 99% cpu 10:49.92 total
и (используя grep
в том же файле для подсчета вхождений a
)
grep -c a /big/basile/backup.tar.xz 38.30s user 7.60s system 33% cpu 2:17.06 total
общий ответ на ваш вопрос:
Просто Запись Умно (с эффективным O (log n) сложность времени структуры данных : красно-черные деревья или хеш-таблицы и т. Д.) эквивалентная программа на C или C ++ или Ocaml или большинстве других хороших языков и реализаций . Или купить больше оперативной памяти, чтобы увеличить кэш страницы . Или купите SSD для хранения ваших данных. И повторяйте свои тесты более одного раза (из-за кеша страниц).
предложение по вашей проблеме: используйте реляционную базу данных
Вероятно, использование простого текстового файла объемом 300 Гбайт не лучший подход. Наличие огромных текстовых файлов обычно неправильно и может быть неправильным, если вам нужно обработать несколько раз одних и тех же данных. Вам лучше предварительно обработать как-нибудь ..
Если вы повторите один и тот же grep
поиск или awk
выполнение для одного и того же файла данных более одного раза, рассмотрите вместо этого использование sqlite (см. также этот ответ) или даже некоторую другую реальную реляционную базу данных (например, с PostGreSQL или другую хорошую СУБД) для хранения и обработки исходных данных.
Таким образом, возможный подход (если у вас достаточно места на диске) может состоять в том, чтобы написать какую-то программу (на C, Python, Ocaml и т. Д.), Снабженную вашими исходными данными, и заполнить некоторую базу данных sqlite
. Убедитесь, что у вас есть умные индексы базы данных и потребуется design достаточно хорошая схема базы данных , помня о нормализации базы данных .