awk fuga de memoria?


11

Base en esto , estoy ejecutando el comando

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

Noté que la memoria utilizada por awk crece continuamente mientras se ejecuta este comando, por ejemplo, consumiendo más de 500 MB de memoria para cuando se han reproducido 75 MB de datos de audio sin formato. Todos los otros comandos en la tubería mantienen una cantidad constante de memoria.

¿Para qué sirve awk usar esta memoria? ¿Existe alguna alternativa que procese el flujo previsto utilizando solo una cantidad constante de memoria?


en caso de que la versión awk importe:

 awk --version
awk version 20070501

Aquí está el comando que probé basado en la respuesta de 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

También veo una pérdida de memoria en mi sistema BSD-Darwin (Mac).
Oteo

Usted dijo Here's the command I tested...pero olvidó decirnos el resultado de esa prueba: ¿resolvió el problema o no? Puede que no, ya que cada referencia a un elemento en a[]el bucle crearía entradas si no existieran, de lo contrario, ¿ayuda si elimina explícitamente la matriz antes de dividirla o después de usarla, por ejemplo 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)) }'? Con ese segmento de código, debe dejar el split () en su ubicación original, no moverlo a BEGIN.
Ed Morton

Respuestas:


11

Esta afirmación es extraña:

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

Divide repetidamente una cadena constante para crear una matriz a. Si mueve eso a una BEGINsección, el programa debería funcionar igual, sin asignar una nueva copia de la amatriz para cada registro de entrada.

Comentarios de direccionamiento: el for-loop y la expresión no asignan memoria de manera simple. Una comparación rápida de mawk, gawk y awk muestra que no hay ningún problema con los dos primeros, pero /usr/bin/awken OSX se filtra rápidamente. Si Apple tuviera un sistema de informe de errores, ese sería el lugar para ir.


1
Hice lo que me sugirió en mi Mac (no soy el OP). Todavía veo una pérdida de memoria con awk.
Oteo

De alguna manera, sólo tiene que hacer referencia a la una memoria usos de patata.
Oteo

Igual que aquí; Todavía veo el crecimiento de la memoria. También hice una comparación aproximada y el uso de memoria parece estar creciendo al mismo ritmo con este cambio.
bames53

Incluso esto causará una pérdida de memoria:awk 'BEGIN { split("0,2,4,5,7,9,11,12",a,","); } { for (i = 0; i < 1; i+= 0.0001) a[1]; }'
Otheus

Podrías cambiar a mawk o gawk. El sistema base de Apple incluye algunas antigüedades reales.
Thomas Dickey

5

Aquí hay un equivalente perl que no se filtra:

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) }'

Es casi idéntico $1se reemplaza por $F[0]y ise reemplaza por $i. El hash aes reemplazada con una matriz real, @a.

Sería aconsejable generar algo de entrada y comparar la salida y observar las diferencias entre los dos. A menudo hay matices en cuanto a cómo los lenguajes interpretativos tratan el punto flotante.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.