Un patrón que he encontrado varias veces ahora es uno en el que se debe verificar una lista de valores mapeando alguna prueba sobre él y ver si alguno o todos los elementos pasaron. La solución típica es usar los convenientes elementos integrados all
y any
.
El problema es que estos se evalúan en serie. En muchos casos, sería mucho más rápido evaluar en paralelo con el proceso completo una vez que cualquier hilo encuentre un "Falso" para all
o un "Verdadero" para any
. Estoy bastante seguro de que el comportamiento de cortocircuito no se puede implementar usando Control. Paralelo, ya que requiere comunicación entre procesos y no entiendo lo suficiente de Control.Concurrent para implementar esto todavía.
Es un patrón bastante común en matemáticas (por ejemplo, Miller-Rabin Primality), por lo que siento que alguien probablemente ya ha encontrado una solución para esto, pero por razones obvias haciendo una búsqueda en Google de "paralelo o / y / cualquiera / todo en la lista haskell "no devuelve muchos resultados relevantes.
fuente
unamb
bibliotecapthreads
en C o subprocesos verdes en Haskell) ¡Usted no inicia múltiples servidores web para manejar solicitudes web concurrentes, en su lugar ejecuta múltiples subprocesos en un solo proceso! Lo mismo se aplica al paralelismo. Gira tantos subprocesos como CPU y divide su trabajo de manera uniforme, por lo que se encarga de las tareas vinculadas a la CPU. Pruebe esta biblioteca para convencerse a sí mismo github.com/lehins/haskell-schedulerRespuestas:
En muchos programas realistas, puede usar estrategias paralelas para este propósito. Esto se debe a que, aunque no existe un mecanismo explícito para cancelar los cálculos innecesarios, esto sucederá implícitamente cuando se ejecute el recolector de basura. Como ejemplo concreto, considere el siguiente programa:
Utiliza una estrategia de lista paralela para buscar
waldo = 0
(que nunca se encontrará) en la salida de 100 flujos PRNG de 40 millones de números cada uno. Compilar y ejecutarlo:y fija cuatro núcleos durante unos 16 segundos, eventualmente imprimiendo
False
. Tenga en cuenta en las estadísticas que las 100 chispas se "convierten" y se ejecutan hasta su finalización:Ahora, cambie
waldo
a un valor que se pueda encontrar temprano:y modifique
main
para mantener vivo el hilo durante 10 segundos:Observará que se imprime
True
casi de inmediato, pero 4 núcleos permanecen vinculados al 100% de la CPU (al menos durante un tiempo), lo que ilustra que los cálculos innecesarios siguen ejecutándose y no están en cortocircuito, como podría haber temido.PERO , las cosas cambian si fuerza una recolección de basura después de obtener la respuesta:
Ahora, verá que la CPU queda inactiva poco después de la impresión
True
, y las estadísticas muestran que la mayoría de los cálculos se recolectaron como basura antes de ejecutarse:En los programas realistas,
performGC
no se necesitará un mensaje explícito , ya que los GC se realizarán regularmente de forma habitual. Algunos cálculos innecesarios continuarán ejecutándose después de encontrar la respuesta, pero en muchos escenarios realistas, la fracción de cálculos innecesarios no será un factor particularmente importante.En particular, si la lista es grande y cada prueba individual de un elemento de la lista es rápida, las estrategias paralelas tendrán un excelente rendimiento en el mundo real y es fácil de implementar en el negocio.
fuente