awk витоку пам'яті?


11

На основі цього я запускаю команду

< /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

Я також бачу витік пам'яті в моїй системі BSD-Darwin (Mac).
Отей

Ви сказали, 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)) }'? За допомогою цього кодового сегмента потрібно залишити спліт () у своєму початковому місці, а не переміщувати його на BEGIN.
Ед Мортон

Відповіді:


11

Це твердження є дивним:

split("0,2,4,5,7,9,11,12",a,",");

Він повторно розбиває постійний рядок для створення масиву a. Якщо ви перемістите це в BEGINрозділ, програма повинна працювати однаково - не виділяючи нову копію aмасиву для кожного вводу-запису.

Звернення до коментарів: for-цикл та вираз не виділяють пам'ять просто. Швидке порівняння mawk, gawk і awk показує, що немає проблем з першими двома, але /usr/bin/awkна OSX швидко протікає. Якби в Apple була система звітування про помилки, це було б саме місце.


1
Я зробив так, як ви запропонували на моєму Mac (я не ОП). Я все ще бачу витік пам'яті з awk.
Отей

Так чи інакше, просто посилання на а пам'ять хеш використовує.
Отей

Те ж саме; Я все ще бачу зростання пам’яті. Я також провів грубе порівняння, і використання пам'яті, схоже, зростає з тією ж швидкістю.
bames53

Навіть це спричинить витік пам’яті:awk 'BEGIN { split("0,2,4,5,7,9,11,12",a,","); } { for (i = 0; i < 1; i+= 0.0001) a[1]; }'
Отей,

Ви можете перейти на маук або гаук. Базова система Apple включає кілька справжніх антикваріатів.
Томас Дікі

5

Ось еквівалент perl, який не протікає:

perl -lne 'BEGIN { @a=(0,2,4,5,7,9,11,12);}
   for ($i = 0; $i < 1; $i+= 0.0001) {
     printf("%08X\n", 100*sin(1382*exp($a[$F[0] % 8]/12)*log(2))*$i) }'

Це майже ідентично. $1замінюється на $F[0]і iзамінюється на $i. Хеш aзамінюється фактичним масиву @a.

Було б розумним створити деякий вклад і порівняти різниці між результатами та відзначити між ними. Часто є нюанси щодо того, як інтерпретаційні мови мають справу з плаваючою точкою.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.