Estoy tratando de entender los futuros de Clojure, y he visto ejemplos de los libros comunes de Clojure, y hay ejemplos donde los futuros se usan para cálculos paralelos (lo que parece tener sentido).entendiendo Clojure futuros
Sin embargo, espero que alguien pueda explicar el comportamiento de un ejemplo simple adaptado del libro Programación Clojure de O'Reilly.
(def long-calculation (future (apply + (range 1e8))))
cuando trato de eliminar la referencia de este, haciendo
(time @long-calculation)
Se devuelve el resultado correcto (4999999950000000), pero casi al instante (en 0.045 milisegundos) en mi máquina.
Pero cuando llamo a la función real, al igual que
(time (apply + (range 1e8)))
puedo obtener el resultado correcto también, pero el tiempo empleado es mucho más grande (~ 5000 milisegundos).
Cuando elimino el futuro, entiendo que se crea un nuevo hilo en el que se evalúa la expresión, en cuyo caso también esperaría que tardara unos 5000 mseg.
¿Cómo es que el futuro desreferenciado devuelve el resultado correcto tan rápido?
¿Hay una desventaja de utilizar un gran número de futuros? He estado escribiendo un código que hace cálculos numéricamente intensivos en varios lugares. En lugar de utilizar matrices nativas de Java o hacer insinuaciones de tipo, ¿puedo simplemente escribir el código funcional idiomático y 'futuro' los resultados de estos cálculos en su lugar? – endbegin
Los futuros son bastante livianos pero tienen algunos gastos generales, así que evitaría usarlos para cálculos extremadamente pequeños. Si desea hacer cálculos en paralelo, considere usar 'pmap', que es una versión concurrente de' map' que usa futuros bajo el capó. Habiendo dicho eso, si su código realmente es numéricamente intensivo, probablemente sea mejor utilizar ambas matrices Java * y * pmap/futuros si quiere sacar lo mejor de su tiempo de CPU. – mikera
He intentado jugar con pmap, pero lo he encontrado útil solo cuando el tamaño de los datos es "grande" (qué tan grande es algo subjetivo, por supuesto). He estado aprendiendo Clojure mediante la implementación de algunas funciones simples de procesamiento de señales digitales, y hay una notable ventaja de velocidad con el uso de matrices Java nativas sobre un estilo funcional con la abstracción seq en el modo de procesador único/hilo. Si utilizo futuros, la aceleración es tan inmensa que realmente no importa si uso un código nativo o funcional. Siente que me falta algo obvio. – endbegin