Интересно, могли бы вы сэкономить время, не открывая и не закрывая awk uuidgen
каждую строку.
$ function regen() { while true; do uuidgen; done; }
$ coproc regen
$ awk -v f="$filename" '!(getline line < f){exit} {print $0,line}' OFS="|" < /dev/fd/${COPROC[0]} > "$filename".pk
При этом awk считывает ваше "настоящее" имя файла из переменной и uuid из stdinпотому что вызов uuidgen обрабатывается с помощью bash " coprocess ".Самое интересное в getline
состоит в том, чтобы сказать awk, что нужно выйти, когда закончится ввод из $filename
.Кроме того, обратите внимание, что awk получает ввод от перенаправления ввода вместо непосредственного чтения файла.Это важно;дескриптор файла на /dev/fd/##
является bash , и awk не может его открыть.
Теоретически это должно сэкономить ваше время на выполнение ненужных системных вызовов для открытия, запуска и закрытия uuidgen
двоичный.С другой стороны, сопроцесс в любом случае делает почти то же самое, выполняя uuidgen
в цикле.Возможно, вы увидите некоторое улучшение в среде SMP.У меня нет текстового файла на 50 ГБ, пригодного для сравнительного анализа.Мне бы очень хотелось услышать ваши результаты.
Обратите внимание, что coproc
- это функция, которая была представлена в bash версии 4. А для использования /dev/fd/*
требуется, чтобы bash был скомпилирован с поддержкой файловых дескрипторов.В моей системе это также означает, что я должен убедиться, что fdescfs(5)
смонтирован.
Я только что заметил в своей системе следующее (FreeBSD 11):
$ /bin/uuidgen -
usage: uuidgen [-1] [-n count] [-o filename]
Если ваш uuidgen
также имеет опцию -n
, то добавление его в вашу функцию regen()
со значением ЛЮБОЕ может быть полезной оптимизацией, чтобы уменьшить количество повторных открытий команды.Например:
$ function regen() { while true; do uuidgen -n 100; done; }
Это приведет к тому, что uuidgen будет вызываться только один раз каждые 100 строк ввода, а не для каждой строки.
А если вы работаете в Linux,в зависимости от того, как вы настроены, у вас может быть альтернативный источник для UUID.Примечание:
$ awk -v f=/proc/sys/kernel/random/uuid '{getline u<f; close(f); print u,$0}' OFS="|" "$filename" "$filename".pk
Для этого не требуется bash coproc
, он просто читает awk случайным образом uuid непосредственно из функции ядра Linux, которая их предоставляет.Вы по-прежнему закрываете дескриптор файла для каждой строки ввода, но, по крайней мере, вам не нужно выполнять исполняемый файл uuidgen.
YMMV.Я не знаю, с какой ОС вы работаете, поэтому я не знаю, что может сработать для вас.