2012-01-31 13 views
7

Estoy considerando convertir una aplicación C# a Haskell como mi primer proyecto Haskell "real". Sin embargo, quiero asegurarme de que sea un proyecto que tenga sentido. La aplicación recoge paquetes de datos de ~ 15 transmisiones en serie que vienen a alrededor de 1 kHz, carga esos valores en los buffers circulares correspondientes en mi objeto de "contexto", cada uno con ~ 25000 elementos, y luego a 60 Hz los envía a OpenGL para visualización de forma de onda. (Por lo tanto, tiene para ser almacenado como una matriz, o al menos convertido a una matriz cada 16 ms). También hay aproximadamente 70 campos en mi objeto de contexto que solo mantengo el valor actual (más reciente), no la forma de onda de la secuencia.¿Es posible crear arreglos de memoria circular grandes y rápidos para grabar en Haskell?

Hay varios aspectos de este proyecto que se corresponden bien con Haskell, pero lo que más me preocupa es el rendimiento. Si para cada nuevo punto de datos en cualquiera de las secuencias, tengo que clonar todo el objeto de contexto con 70 campos y 15 matrices de 25000 elementos, obviamente habrá problemas de rendimiento.

¿Lo solucionaría poniendo todo en la IO-mónada? Pero luego eso parece de alguna manera frustrar el propósito de usar Haskell, ¿verdad? Además, todo mi código en C# está basado en eventos; ¿Hay un idioma para eso en Haskell? Parece que agregar un oyente crea un "efecto secundario" y no estoy seguro de cómo se haría exactamente eso.

Respuesta

5

Sí, es probable que desee utilizar la mónada IO para datos mutables. No creo que la mónada ST sea adecuada para este espacio problemático porque las actualizaciones de datos están intercaladas con acciones IO reales (lectura de flujos de entrada). Como necesitaría realizar el IO dentro de ST usando unsafeIOToST, me parece preferible usar IO directamente.El otro enfoque con ST es descongelar y congelar continuamente una matriz; esto es complicado porque debe garantizar que nunca se usen copias antiguas de los datos.

Aunque evidence shows que una solución pura (en forma de Data.Sequence.Seq) es a menudo más rápido que utilizando los datos mutables, dada su requerimiento de que los datos puedan empujar hacia afuera a OpenGL, usted puede obtener un mejor rendimiento al trabajar con la matriz directamente. Utilizaría las funciones de Data.Vector.Storable.Mutable (del paquete de vectores), ya que tiene acceso al ForeignPtr para exportar.

Puede ver las flechas (Yampa) para obtener un enfoque muy común del código basado en eventos. Otra área es la reactividad funcional (FRP). Están comenzando a existir algunas bibliotecas razonablemente maduras en este campo, como Netwire o el plátano reactivo. No sé si proporcionarían un rendimiento adecuado para sus requisitos; Los he usado principalmente para la programación de tipo gui.

7

mirada a este enlace, en la sección "La mónada ST":

http://book.realworldhaskell.org/read/advanced-library-design-building-a-bloom-filter.html

De vuelta en la sección denominada “Modificación de elementos de la matriz”, mencionamos que la modificación de una serie inmutable es prohibitivamente costoso, ya que requiere copiar toda la matriz. El uso de un UArray no cambia esto, entonces, ¿qué podemos hacer para reducir el costo a niveles soportables?

En un lenguaje imperativo, simplemente modificaríamos los elementos de la matriz en su lugar; este será nuestro enfoque en Haskell, también.

Haskell proporciona una mónada especial, llamada ST, que nos permite trabajar de forma segura con el estado mutable. Comparado con la mónada de estado, tiene algunas capacidades agregadas de gran alcance .

Podemos descongelar una matriz inmutable para obtener una matriz mutable; modificar la matriz mutable en su lugar; y congelar una nueva matriz inmutable cuando estamos hecho.

...

La mónada IO también proporciona estas capacidades. La principal diferencia entre los dos es que la mónada ST está diseñada intencionalmente para que podamos escapar de ella nuevamente en el código Haskell puro.

Por lo tanto, debería ser posible modificar en el lugar, y después de todo no se frustrará el propósito del uso de Haskell.

Cuestiones relacionadas