У меня большой текстовый файл (1,5 Г),
Я хочу знать, какой самый быстрый и надежный инструмент в Linux.
Я обычно использую:
awk '!x[$0]++' file.txt
Но когда я использую htop
команду, я вижу, что использование моей памяти увеличивается.
Я хочу знать, что является самым быстрым и надежным для больших файлов.
uniq?
sort?
sed?
awk?
Почему?
time
?Ответы:
Давайте рассмотрим, как работает каждое решение.
uniq
Это требует, чтобы файл уже был отсортирован. Если нет,sort
сначала нужно передать его по конвейеру , что означает, чтоsort
необходимо прочитать весь файл в память, переупорядочить его (O(n log n)
), а затем записать в конвейер. Работаuniq
очень дешевая, так как нужно только сравнить соседние строки ввода.sort -u
Это сочетает в себе работуsort | uniq
. Это должно собирать все уникальные входные данные в память, как этоawk
делает сценарий, но также тратить время на их сортировку перед созданием выходных данных. Это такO(n log n)
, хотя в данном случаеn
это количество уникальных предметов, а не все входы. Так что лучше, чем труба.sed
Я не уверен, почему вы перечислили это, так как я не могу придумать хороший способ сделать этоsed
вообще. Возможно, если вы сначала отсортируете его и передадите вsed
скрипт, есть способ сравнить соседние строки. Такsed
что будет просто делать тоuniq
, что делает, и,uniq
вероятно, делает это максимально эффективно.awk
Это, вероятно, лучше, потому что он выполняет только минимальный объем работы, необходимый. Когда он читает каждую строку, он выполняет эффективный поиск хеша, чтобы увидеть, находится ли строка в ее памяти, и сохраняет только уникальные строки в качестве ключей хеша, а счетчик - в качестве значения. (Если строка ранее не присутствовала, условие будет истинным, поэтому строка будет напечатана. В противном случае это не будет.) Это используетO(n)
время иO(uniq n)
память.Каждый метод будет использовать значительный объем памяти, либо для сортировки ввода, либо для отслеживания того, какие входы видели, чтобы они могли удалить дубликаты.
источник
awk
также объясняет, почему это использует увеличивающиеся количества памяти. Все, что выполняет сортировку, в конечном итоге также будет делать это, только 1) оно, вероятно, будет использовать все сразу, 2) оно может использовать немного больше, в зависимости от количества уникальных и дублированных ключей.sort
прибегает к временным файлам (интеллектуальным способом), чтобы избежать заполнения памяти. Его использование памяти связано. Граница настраивается с помощью некоторых видов реализации. Это более эффективно, чем позволить системе произвольно перезаписывать память на диск (что также влияет на приложения в системе).awk
хватает памяти,sort
может быть единственным решением, потому что оно было разработано для решения этой проблемы. С другой стороны, все это чтение и запись на диске замедлит его, поэтому, вероятно, это займет много времени. Если вы имеете дело с такими большими объемами данных, вам, вероятно, следует использовать СУБД, а не текстовые файлы.O(n log n)
? Или просто ты знаешь это откуда-то еще?Я обнаружил, что этот вид, кажется, самый быстрый инструмент uniq, как показано здесь -> Самый быстрый способ удалить дубликаты в большом списке слов?
источник
Я просто хотел указать, что GNU
uniq
кажется ужасно медленным, даже в отсортированном списке.Я просто попытался получить список префиксов каталогов из списка отсортированных имен файлов:
sort -u кажется в два раза быстрее, чем uniq, и это при чтении сортировки из stdin и записи в stdout, поэтому я пока не вижу, чтобы это делало распараллеливание. Я понятия не имею, почему uniq должен быть намного медленнее, чем сортировать, поскольку он не должен сортировать список ...
Результат этой команды очень мал (есть много дубликатов), только 264 КБ и сортировка завершается сразу после выполнения pv.
Те же скорости остаются, если вы меняете порядок команд, мой поток ограничен здесь временем процессора, а не доступом к диску и кешами (у меня только 8 ГБ ОЗУ, и мой подкачка не используется)
Я запускаю это на машине fedora 31 с GNU Coreutils и UniQ и GNU AWK; локаль установлена в en_US.UTF-8
ОБНОВЛЕНИЕ , так как это немного заинтриговало меня, я сделал еще несколько тестов, давайте разберем вырезанную часть и убедимся, что файл хорошо отсортирован
cat all_files | cut -d '/' -f 1,2,3,4 | sort -T . > test
Это займет 8,4 минуты. тест теперь 7,9 ГБ большой
давайте запустим эти инструменты в файле, а не в конвейере, это позволит этим инструментам выполнить дополнительную оптимизацию, например, sort будет multi thread. а также от более быстрого ssd.
Вы можете не заметить, что сортировка также занимает много памяти, так как она делает хитрые трюки с временными файлами в / tmp, которые могут быть tmpfs и будут у вас в памяти (попробуйте отсортировать файл больше, чем / tmp, вы попадете в пространство вопросы, поэтому мне нужен флаг -T. в приведенной выше команде)
Так что, похоже, ваше awk-решение является самым быстрым из этих 3 , и на самом деле использует меньше всего памяти
update2 и теперь с более простым языком
На этот раз uniq действительно выигрывает гонку ... как намекает Стефан Шазелас в комментариях, установка вашего языка на C делает сортировку и uniq целой кучей быстрее!
источник
sort
аuniq
? Какой язык?