Существует ли способ сделать эту остроту быстрее?

Правильный синтаксис:

# vim: set filetype=python:

Но Вам нужно set modeline (это - значение по умолчанию в моем случае) в .vimrc.

Считайте эту Wiki для получения дополнительной информации.

7
09.07.2014, 12:49
3 ответа

Некоторые быстрые идеи;

  • Если все файлы находятся в одном каталоге, вы можете избавиться от find
  • Your file name convention сортирует себя по дате, так что вам не нужен бит сортировки sort
  • С этими двумя кусками, и если диапазон дат известен, вы можете использовать простой глобус с именем файла вместо awk. Например (предположим, что ваша оболочка - bash):

    • Все файлы одного дня

      echo xml_20140207_*.zip | xargs -n 1 -P 10 zipgrep "my search string"

    • Файлы, созданные между 15:00 и 18:00, либо в 07 или 10 февраля 2014:

      echo xml_201402{07,10}_1{5. .7}*.zip | xargs -n 1 -P 10 zipgrep "my search string"

6
27.01.2020, 20:15

Есть часть, которую можно легко улучшить, но это не самая медленная часть.

 find / home / mydir / -type f |  сортировать |  \
awk "/xml_20140207_000016.zip/,/xml_20140207_235938.zip/"
 

Это несколько расточительно, потому что сначала перечисляются все файлы, затем сортируются имена файлов и извлекаются наиболее интересные. Команда find должна быть завершена до начала сортировки.

Было бы быстрее перечислить в первую очередь только интересные файлы или, по крайней мере, как можно меньший надмножество. Если вам нужен более мелкозернистый фильтр по именам, чем может find , переходите в awk, но не сортируйте: awk и другие построчные фильтры могут обрабатывать строки одну за другой, но сортировка требует полный ввод.

find /home/mydir/ -name 'xml_20140207_??????.zip' -type f | \
awk 'match($0, /_[0-9]*.zip$/) &&
     (time = substr($0, RSTART+1, RLENGTH-5)) &&
     time >= 16 && time <= 235938' |
xargs -n 1 -P 10 zipgrep "my search string"

Наиболее явно неоптимальной является zipgrep. Здесь нет простого способа повысить производительность из-за ограничений программирования оболочки. Сценарий zipgrep работает, перечисляя имена файлов в архиве и вызывая grep для каждого содержимого файла, один за другим. Это означает, что zip-архив снова и снова анализируется для каждого файла. Программа Java (или Perl, или Python, или Ruby и т. Д.) Может избежать этого, обработав файл только один раз.

Если вы хотите придерживаться программирования оболочки, вы можете попробовать смонтировать каждый zip вместо использования zipgrep.

… | xargs -n1 -P2 sh -c '
    mkdir "mnt$$-$1";
    fuse-zip "$1" "mnt$$-$1";
    grep -R "$0" "mnt$$-$1"
    fusermount -u "mnt$$-$1"
' "my search string"

Обратите внимание, что параллелизм вам не очень поможет: ограничивающим фактором при большинстве настроек будет пропускная способность дискового ввода-вывода, а не время процессора.

Я ничего не тестировал, но думаю, что лучше всего можно было бы улучшить реализацию zipgrep на более мощном языке.

7
27.01.2020, 20:15

Неясно, где находится ваше узкое место. Давайте предположим, что это в чтении файлов. В зависимости от вашей системы хранения, это быстрее прочитать весь файл перед его обработкой. Это особенно верно для Zipgrep , который делает несколько ищет в файле: если файл не полностью в памяти, вы ждете, что диск для поиска.

find ... | parallel -j1 'cat {} >/dev/null; echo {}' | parallel zipgrep "my search string"

Приведенная выше будет CAT CAT один файл за раз и тем самым положить его в кэш памяти, затем запустить один Zipgrep на CPU, который затем прочитал из кеша памяти.

Я использовал RAID Systems, в которых вы получили 6x скорость, чтение 10 файлов параллельно, чем считывание 1 файла за раз или считывание 30 файлов параллельно. Если бы мне пришлось бежать выше на эту систему RAID, я бы отрегулировал -J1 - 1 -J10 .

Используя GNU Parallel вместо xargs , вы охраняете себя от смешивания вывода (см. http://www.gnu.org/software/parallel/man.html#differences-betwen -xargs-and-gnu-параллель ).

3
27.01.2020, 20:15

Теги

Похожие вопросы