依据这我正在运行命令
< /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 使用的内存不断增长,例如,在播放 75MB 的原始音频数据时,消耗了超过 500MB 的内存。管道中的所有其他命令都保持恒定的内存量。
awk 使用此内存的目的是什么?是否有替代方案仅使用恒定量的内存来进行预期的流处理?
如果 awk 版本很重要:
⑆ awk --version
awk version 20070501
这是我根据 Thomas Dickey 的答案测试的命令:
< /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
答案1
这个说法很奇怪:
split("0,2,4,5,7,9,11,12",a,",");
它重复分割常量字符串以创建数组a
。如果将其移动到一个BEGIN
部分中,程序应该以相同的方式工作 - 无需a
为每个输入记录分配数组的新副本。
解决注释:for循环和表达式并不以简单的方式分配内存。对 mawk、gawk 和 awk 的快速比较表明前两者没有问题,但/usr/bin/awk
在 OSX 上泄漏确实很快。如果苹果有一个错误报告系统,那将是一个不错的选择。
答案2
这是一个不会泄漏的 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
。
您最好生成一些输入并比较输出并注意两者之间的差异。解释性语言如何处理浮点通常存在细微差别。