Основываясь на этом, я управляю командой
< /dev/urandom hexdump -v -e '/1 "%u\n"' |
awk '{ split("0,2,4,5,7,9,11,12",a,",");
for (i = 0; i < 1; i+= 0.0001)
printf("%08X\n", 100*sin(1382*exp((a[$1 % 8]/12)*log(2))*i)) }' |
xxd -r -p |
sox -traw -r44100 -b16 -e unsigned-integer - -tcoreaudio
Я заметил, что объем памяти, используемой awk, постоянно увеличивается во время выполнения этой команды, например, он потребляет более 500 МБ памяти к моменту воспроизведения 75 МБ необработанных аудиоданных. Все остальные команды в конвейере поддерживают постоянный объем памяти.
Для чего awk использует эту память, и есть ли альтернатива, которая предназначена для обработки потока, используя только постоянный объем памяти?
если версия awk имеет значение:
⑆ awk --version
awk version 20070501
Вот команда, которую я протестировал на основе ответа Томаса Дики:
< /dev/urandom hexdump -v -e '/1 "%u\n"' |
awk 'BEGIN { split("0,2,4,5,7,9,11,12",a,",") }
{ for (i = 0; i < 1; i+= 0.0001)
printf("%08X\n", 100*sin(1382*exp((a[$1 % 8]/12)*log(2))*i)) }' |
xxd -r -p |
sox -traw -r44100 -b16 -e unsigned-integer - -tcoreaudio
Here's the command I tested...
но забыли сообщить нам результат этого тестирования - это решило проблему или нет? Это может не произойти, поскольку каждая ссылка на элемент вa[]
цикле создаст записи, если они не существуют, а если нет, то поможет ли это, если вы явно удалите массив перед его разбиением или после его использования, напримерawk '{ delete a; split("0,2,4,5,7,9,11,12",a,","); for (i = 0; i < 1; i+= 0.0001) printf("%08X\n", 100*sin(1382*exp((a[$1 % 8]/12)*log(2))*i)) }'
? С этим сегментом кода вам нужно оставить split () в исходном месте, а не перемещать его в BEGIN.Ответы:
Это утверждение странно:
Повторно разбивает постоянную строку для создания массива
a
. Если вы перемещаете это вBEGIN
раздел, программа должна работать так же - без выделения новой копииa
массива для каждой входной записи.Адресация комментариев: цикл for и выражение не выделяют память простым способом. Быстрое сравнение mawk, gawk и awk показывает, что с первыми двумя проблем нет, но
/usr/bin/awk
в OSX происходит утечка быстро. Если бы у Apple была система сообщений об ошибках, это было бы подходящим вариантом.источник
awk 'BEGIN { split("0,2,4,5,7,9,11,12",a,","); } { for (i = 0; i < 1; i+= 0.0001) a[1]; }'
Вот эквивалент Perl, который не пропускает:
Это почти идентично.
$1
заменяется на$F[0]
иi
заменяется на$i
. Хешa
заменяется фактическим массивом@a
.Было бы целесообразно сгенерировать некоторые входные данные и сравнить выходные данные и отметить различия между ними. Часто возникают нюансы того, как интерпретирующие языки работают с плавающей запятой.
источник