Usar Clojure en lugar de Python por razones de escalabilidad (multi-core), ¿buena idea? [cerrado]

8

Después de leer http://clojure.org/rationale y otras comparaciones de rendimiento entre Clojure y muchos idiomas, comencé a pensar que, además de la facilidad de uso, ya no debería codificar en Python, sino en Clojure. En realidad, comencé a sentirme irresponsable por no aprender Clojure, viendo sus beneficios.

¿Tiene sentido? ¿No puedo hacer un uso realmente eficiente de todos los núcleos usando un lenguaje más imperativo como Python, que un dialecto Lisp u otro lenguaje funcional? Parece que todos los beneficios provienen del uso de datos inmutables, ¿no puedo hacer eso en Python y tener todos los beneficios?

Una vez comencé a aprender Common Lisp, leí e hice casi todos los ejercicios de un libro que tomé prestado de la biblioteca de mi universidad (encontré que era bastante bueno, a pesar de su baja popularidad en Amazon). Pero, después de un tiempo, me encontré luchando demasiado para hacer algunas cosas simples. Creo que hay algunas cosas que son más imperativas en su naturaleza, que dificultan modelar esas cosas de una manera funcional.

Entonces, ¿es Python tan poderoso como Clojure para crear aplicaciones que aprovechen este nuevo futuro de múltiples núcleos?

Tenga en cuenta que no creo que el uso de semáforos, mecanismos de bloqueo u otro mecanismo de concurrencia similar sean buenas alternativas a la paralelización 'automática' de Clojure.

Julio Rodrigues
fuente
55
En función de lo que parece estar tratando de lograr, también debería considerar erlang .
Jerry Coffin
2
Todavía no está aquí, y puede que nunca funcione bien, pero los planes de STM de los chicos de PyPy (bueno, en su mayoría uno: Armin Rigo) suena genial y está tangiblemente relacionado con esta pregunta.

Respuestas:

4

¿No puedo hacer un uso realmente eficiente de todos los núcleos utilizando un lenguaje más imperativo como Python, que un dialecto lisp u otro lenguaje funcional?

Definitivamente puedes . Dependiendo del tipo de problema (por ejemplo, procesar porciones claramente separables de alguna gran tarea computativa en paralelo), incluso puede ser bastante fácil. Supongo que la mayor parte de la concurrencia en el mundo todavía se realiza directamente en lenguajes imperativos, aunque el paradigma está cambiando hacia soluciones funcionales.

Sin embargo, Python no es exactamente conocido por sus capacidades de concurrencia. Un ejemplo de un lenguaje imperativo bien establecido con excelente soporte de concurrencia es Java.

Parece que todos los beneficios provienen del uso de datos inmutables, ¿no puedo hacer eso en Python y tener todos los beneficios?

El truco con los datos inmutables es que, si lo hace con las estructuras de datos simples y tradicionales, como las matrices, terminará con la copia masiva y la recolección de basura, arruinando el rendimiento. En cambio, desea datos efectivamente inmutables , que se pueden implementar con varias estructuras de datos persistentes , como se hace en Clojure bajo el capó. Dichas estructuras podrían realizarse en casi cualquier idioma como bibliotecas, pero, por supuesto, el soporte directo de idiomas siempre es mejor.

Joonas Pulakka
fuente
8

Python es extremadamente malo para las aplicaciones que necesitan múltiples subprocesos, pero es causado por una deficiencia en las máquinas virtuales disponibles, no en el lenguaje en sí. Los generadores de Python realmente serían buenos candidatos para la paralelización implícita. El problema es que la implementación estándar, CPython, solo puede ejecutar código python en una CPU, solo las llamadas en bibliotecas nativas pueden ejecutarse en paralelo. El tiempo de ejecución de PyPy planea solucionarlo, pero aún no está allí y, aunque las implementaciones de Jython e IronPython no tienen la limitación, son bastante incompletas (no tienen gran parte de la biblioteca estándar, debe usar la biblioteca estándar) del entorno de alojamiento en ellos).

Sin embargo, hay muchos otros lenguajes diseñados e implementados con paralelismo. Por supuesto, el paralelismo es mucho más fácil en los lenguajes funcionales, por lo que todos los lenguajes con buen soporte de paralelismo son funcionales o tienen un fuerte soporte para la programación funcional. Puedo pensar en:

  • Haskell , el lenguaje funcional puro, no estricto más utilizado. Su naturaleza pura y no estricta permite al compilador paralelizar algunas cosas implícitamente.
  • Erlang es un lenguaje funcional estricto diseñado específicamente para implementar servidores paralelos robustos, con soporte incorporado para distribución a clústeres.
  • Clojure, por supuesto. Al igual que otros lisps, está diseñado para la programación funcional, pero también admite la programación imperativa.
  • Go es un nuevo lenguaje procesal compilado diseñado para la concurrencia, aunque ni los tiempos de ejecución ni el lenguaje en sí son muy maduros todavía.
  • Rust es un nuevo lenguaje procesal compilado diseñado para la concurrencia, la baja sobrecarga y la comprobación estática de la memoria y la seguridad de la concurrencia. No muy maduro todavía tampoco.
Jan Hudec
fuente
Go acaba de tener su versión 1.0 después de unos dos años de desarrollo de código abierto.
Sonia
1
Y Python tiene el paquete de multiprocesamiento.
Sonia
Realmente no sabía que Haskell puede ser rápido (más rápido que Python). Lo aprendí en mi primer curso de programación, definitivamente necesito verlo nuevamente.
Julio Rodrigues
1
@Vandell: Haskell es un lenguaje compilado estáticamente escrito, por lo que es mucho más rápido. Según The Computer Language Benchmarks Game , Haskell es más o menos comparable a Java y Mono.
Jan Hudec
@Sonia: ... que es lo que yo llamo no muy maduro. Por lo general, lleva 10 años o más para que se establezca la especificación del idioma. Al menos espero que Go siga Java y C # y obtenga genéricos algún día.
Jan Hudec
2

Los muchachos aquí dieron respuestas realmente excelentes.

La programación concurrente suele ser difícil debido al "estado compartido". La programación funcional puede no ser la respuesta definitiva, pero seguramente la hará posible sin perder el pelo.

Clojure seguro es una opción viable, pero incluso con sus excelentes herramientas de concurrencia, es posible que necesite construir algo más. Verifique Prismatic para ver un ejemplo:

Nuestra elección del idioma del backend es Clojure en la JVM. Hay otros lenguajes funcionales excelentes en la JVM, como Scala, pero lo que nos gusta de Clojure es que tiene un núcleo pequeño y simple centrado en el procesamiento de datos representados en su excelente conjunto de estructuras de datos persistentes (o sus equivalentes mutables java.util, cuando surge la necesidad). Si bien hacemos un uso intensivo del núcleo de Clojure, no utilizamos sus primitivas de concurrencia (átomos, referencias, STM, etc.) porque una función como pmap no tiene suficiente control de grano fino para nuestras necesidades. En su lugar, optamos por construir nuestras propias abstracciones de concurrencia en Clojure sobre el paquete java.util.concurrent pendiente.

Si realmente quiere enloquecer, consulte también el lenguaje de programación Julia .

Julia no impone ningún estilo particular de paralelismo al usuario. En cambio, proporciona una serie de bloques de construcción clave para el cálculo distribuido, lo que lo hace lo suficientemente flexible como para admitir una serie de estilos de paralelismo y permite a los usuarios agregar más.

Quirón
fuente
2

Además de lo que escribió Jan Hudec, me gustaría mencionar a Scala que, además de un estilo de programación funcional, también admite un estilo de programación imperativo / orientado a objetos.

Scala ofrece paralelismo a través de actores (también utilizados por Erlang).

Tenga en cuenta que no creo que el uso de semáforos, mecanismos de bloqueo u otro mecanismo de concurrencia similar sean buenas alternativas a la paralelización 'automática' de Clojure.

Los actores son una forma orientada a objetos de abstraerse de los hilos / procesos subyacentes: básicamente solo se ven objetos que se ejecutan simultáneamente y se envían mensajes entre sí. Por lo tanto, si desea una forma orientada a objetos de implementar paralelismo, también echaré un vistazo a los lenguajes (o marcos) que admiten el modelo de actor.

Puede encontrar algunos enlaces en wikipedia , para Python hay, por ejemplo, Pykka .

Giorgio
fuente