に従ってこれコマンドを実行しています。
< /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をすばやく比較すると、最初の2つに問題はありませんが、/usr/bin/awk
OSXでは非常に急速に漏れていることがわかります。 Appleにバグレポートシステムがある場合、これは素晴らしい選択肢になります。
答え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
。
いくつかの入力を生成し、出力を比較し、違いを確認することをお勧めします。解釈された言語が浮動小数点を処理する方法には微妙な違いがあることがよくあります。