Darauf aufbauend führe ich den Befehl aus
< /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
Ich stelle fest, dass der von awk verwendete Speicher während der Ausführung dieses Befehls kontinuierlich wächst und beispielsweise über 500 MB Speicher verbraucht, bis 75 MB Roh-Audiodaten abgespielt wurden. Alle anderen Befehle in der Pipeline behalten eine konstante Speichermenge bei.
Wofür verwendet awk diesen Speicher und gibt es eine Alternative, bei der die beabsichtigte Stream-Verarbeitung nur eine konstante Speichermenge verwendet?
falls die awk version wichtig ist:
⑆ awk --version
awk version 20070501
Hier ist der Befehl, den ich basierend auf der Antwort von Thomas Dickey getestet habe:
< /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...
aber Sie haben vergessen, uns das Ergebnis dieser Tests mitzuteilen - hat es das Problem gelöst oder nicht? Möglicherweise nicht, da jeder Verweis auf ein Element ina[]
der Schleife Einträge erstellen würde, wenn sie nicht vorhanden wären. Wenn dies nicht der Fall ist, hilft es, wenn Sie das Array vor dem Teilen oder nach der Verwendung explizit löschen, zawk '{ 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)) }'
. Bei diesem Codesegment müssen Sie split () an seiner ursprünglichen Position belassen und nicht nach BEGIN verschieben.Antworten:
Diese Aussage ist seltsam:
Es teilt wiederholt eine konstante Zeichenfolge, um ein Array zu erstellen
a
. Wenn Sie das in einenBEGIN
Abschnitt verschieben, sollte das Programm genauso funktionieren - ohnea
jedem Eingabedatensatz eine neue Kopie des Arrays zuzuweisen.Adressieren von Kommentaren: Die for-Schleife und der Ausdruck weisen den Speicher nicht auf einfache Weise zu. Ein schneller Vergleich von mawk, gawk und awk zeigt, dass es mit den ersten beiden kein Problem gibt, aber
/usr/bin/awk
unter OSX leckt es schnell. Wenn Apple ein System zur Fehlerberichterstattung hätte, wäre dies der richtige Ort.quelle
awk 'BEGIN { split("0,2,4,5,7,9,11,12",a,","); } { for (i = 0; i < 1; i+= 0.0001) a[1]; }'
Hier ist ein Perl-Äquivalent, das nicht ausläuft:
Es ist fast identisch.
$1
wird ersetzt durch$F[0]
undi
wird ersetzt durch$i
. Der Hasha
wird durch ein tatsächliches Array ersetzt@a
.Es ist ratsam, einige Eingaben zu generieren und die Ausgabe- und Notenunterschiede zwischen den beiden zu vergleichen. Es gibt oft Nuancen, wie interpretierende Sprachen mit Gleitkomma umgehen.
quelle