Sobre el rendimiento y la interoperabilidad de Java: Clojure frente a Scala

82

Ya he leído varios relatos de Clojure vs. Scala y al mismo tiempo me doy cuenta de que ambos tienen su lugar. Hay algunas consideraciones sobre las que no he obtenido una explicación completa cuando se trata de comparar tanto Clojure con Scala:

1.) ¿Cuál de los dos idiomas es generalmente más rápido ? Me doy cuenta de que esto variará de una característica del idioma a otra, pero una evaluación general del desempeño sería útil. Por ejemplo: sé que los diccionarios de Python son muy rápidos. Pero en general, es un lenguaje mucho más lento que Java. No quiero ir con Clojure y encontrarme con este problema en el futuro.

2.) ¿Cómo es la interoperabilidad con Java? Todo lo que he leído hasta ahora es que Scala tiene tipos de colecciones nativas que hacen que sea un poco torpe integrarse con una gran base de código de Java, mientras que Clojure sigue una forma simple Iterable / Iterator-centric para interactuar con las clases de Java. ¿Más pensamientos / detalles sobre esto?

En última instancia, si hay un empate lo suficientemente cercano entre clojure y scala, podría probar ambos. Una cosa sobre Clojure es que el lenguaje parece muy simple. Pero, de nuevo, Scala tiene un sistema de tipos muy flexible. Pero sé que Scala es rápido (basado en múltiples cuentas personales). Entonces, si Clojure es significativamente más lento: me gustaría saberlo más temprano que tarde.

Ryan Delucchi
fuente
1
Con Clojure 1.2, Clojure puede llamar a Java sin gastos generales. Mire assembla.com/wiki/show/clojure/Datatypes y assembla.com/wiki/show/clojure/New_new . Esto se hace porque Clojure quiere estar cerca de Java pero implementado en Clojure.
Nickik

Respuestas:

73

Creo que cualquiera de los dos idiomas será lo suficientemente rápido para ti. Al comparar Python y Java, parece un poco irrazonable culpar al lenguaje por la diferencia de velocidad. Java se compila JIT (excepto en dispositivos móviles *) mientras que Python se interpreta. El hecho de que ambos usen un código de bytes no significa que las implementaciones tendrán un rendimiento ni remotamente comparable. Pero tanto Scala como Clojure son lenguajes JVM, por lo que deberían tener un rendimiento similar.

Scala tiene algunas ventajas de implementación sobre Clojure y esperaría un rendimiento algo mayor. Aunque los tipos estáticos de Scala normalmente traducirse en una ventaja de velocidad sobre la tipificación de pato de Clojure, Clojure hace el tipo de soporte dando a entender que puede acelerar considerablemente código. Posiblemente, Scala ordinario es más rápido que Clojure ordinario, pero solo necesita optimizar los cuellos de botella. La mayor parte del tiempo de ejecución de un programa se genera mediante una pequeña cantidad del código real.

Con respecto a la interoperabilidad con Java, Scala está más cerca de Java, pero estoy seguro de que ambos lenguajes interactúan bien. En Programación Clojure, Stuart Halloway escribe: "[puedes acceder] a cualquier cosa que puedas alcanzar desde el código Java ".

Y dado que el autor de Scala, Martin Odersky, escribió el compilador de Java de Sun, creo que tampoco se han dejado caer pelotas en el lado de Scala. :-)

Sería difícil elegir dos idiomas mejores, aunque a mí también me gusta Ruby. ¿Por qué te preocupa cuál probar? ¿Por qué no probar los dos? Es más probable que Scala sea "el próximo Java", mientras que es difícil imaginar que Lisp finalmente despegue después de no hacerlo durante más de 50 años. Pero está claro que Lisp tiene su propio nivel único de abstracción, y Clojure es bastante simple, por lo que Scala + Clojure no será mucho más difícil que solo (el bastante complejo) Scala y estoy seguro de que se alegrará de haberlo hecho. eso.

Y para el caso, interoperan ...

* dalvik (JVM de Android) obtuvo un compilador JIT en la versión 2.2 en 2010

DigitalRoss
fuente
6
¿Eh? Bueno, gracias por todas las ideas. Al principio, estaba en el modo en el que solo quería elegir uno y ejecutarlo. Pero por alguna razón, no se me ocurrió que podía usar ambos y hacer que interactuaran. Entonces, tal vez elija ambos y haga una caminata rápida con ellos :-)
Ryan Delucchi
7
Y me gustaría agregar que tengo un poco de "debilidad" por LISP, por lo que el hecho de que Clojure sufre de parethesitis no es suficiente para asustarme.
Ryan Delucchi
8
No siempre es cierto que un lenguaje escrito en la JVM funcione a la máxima velocidad. El JRuby original tuvo un rendimiento abismal porque era un intérprete que se compiló en la JVM, no en el código fuente. El idioma también puede ser el culpable. Los lenguajes de escritura estática suelen ser más fáciles de optimizar que los lenguajes dinámicos, etc.
Bill K
7
-1 "Tanto Scala como Clojure son lenguajes JVM por lo que deberían tener un rendimiento similar" no tiene ningún sentido. Lenguajes dinámicos que necesitan para mantenerse interoperable con unas lenguas estáticas como Java son siempre mucho más lento (sobrecarga se produce en un enorme costo, dando a entender tipo no resuelve todos los problemas, etc.)
julx
4
@julkiewicz: simplemente no es cierto que los lenguajes dinámicos sean siempre mucho más lentos. Depende de si su compilador puede hacer un trabajo decente optimizando el código en cuestión. Por ejemplo, en Clojure puedes hacer aritmética con primitivas de Java que coincidan exactamente con el rendimiento de Java. Del mismo modo, llamar a un método en un objeto Java con sugerencia de tipo es tan rápido como llamar a un método de objeto Java. El compilador de Clojure esencialmente produce el mismo código de bytes que javac para el código Java equivalente.
mikera
32

Con la JVM actual, Scala tiene la ventaja de estar tipado estáticamente, ya que el soporte de JVM para tipado dinámico (reflexión) es lento. De hecho, una característica de Scala que debe implementarse mediante las mismas técnicas, los tipos estructurales, a menudo se advierte por esta misma razón.

Además, Scala acepta objetos mutables sin problemas, y algunos algoritmos son más rápidos de implementar con mutabilidad.

Como Scala y Java son esencialmente lenguajes basados ​​en clases, interoperan más fácilmente. O, quizás, de forma más fluida. Una clase Java es una clase para Scala y una clase Scala es una clase para Java. Pueden surgir problemas cuando se trata de los singletons de Scala o de los miembros estáticos de Java, particularmente cuando hay un marco involucrado que espera que las cosas funcionen de cierta manera.

Así que me gustaría ir con Scala en ambas estas cuentas. Clojure es, en muchos sentidos, un lenguaje mejor , y ciertamente tiene características muy interesantes que no están presentes (hasta ahora) en Scala, pero obtienes esos beneficios al ser completamente funcional. Si tiene la intención de hacer eso, es muy probable que Clojure sea mejor. Si no lo hace, probablemente debería quedarse con Scala.

Daniel C. Sobral
fuente
9
Las características de programación funcional de clojure son la razón más convincente por la que estoy considerando este lenguaje. Estoy llegando al punto en el que: si no estoy codificando algo de manera funcional, ¿por qué me molesto con un lenguaje de scripting incrustado en Java de todos modos? Ya tengo Python a mi lado para realizar tareas rápidas y sucias.
Ryan Delucchi
9
Entonces ve con Clojure.
Daniel C. Sobral
"lenguaje de secuencias de comandos incrustado en Java". Por favor justifique.
Jus12
@Daniel: Perdón por la confusión. Me refería al comentario hacia Ryan Delucchi. Dice que Scala es un "lenguaje de secuencias de comandos integrado en Java", que no compro. (A menos que se refiriera a Clojure, de lo que no tengo idea).
Jus12
@ Jus12 Supuse que significa que está usando estos lenguajes como lenguajes de scripting de JVM y, dado eso, no ve ninguna ventaja en ellos sobre Python a menos que se vuelva funcional. Por otra parte, no soy él, así que solo puedo adivinar.
Daniel C. Sobral
20

Tenga en cuenta que Clojure y Scala dos tipos totalmente diferentes de los lenguajes de programación - Clojure es un funcional similar al lenguaje Lisp, se no orientado a objetos. Scala es un lenguaje orientado a objetos que tiene características de programación funcional.

En mi opinión, las características y conceptos de un idioma (funcional, OO, ...) son criterios mucho más importantes para elegir un idioma que el rendimiento (de una implementación particular de ese idioma), aunque entiendo que no quieren quedar atrapados en un lenguaje para el que no existe una implementación de buen rendimiento disponible.

Me decantaría por Scala, porque está orientado a objetos, pero también te permite aprender programación funcional (si estás interesado en eso). Por otro lado, si no te importa OO y quieres aprender programación funcional "pura", prueba Clojure.

Jesper
fuente
9
Claramente no has usado Clojure. Clojure está tan orientado a objetos como Scala es funcional. Puede implementar una interfaz, extender una clase, declarar funciones privadas y estáticas, etc. ( clojure.org/java_interop ).
Richard Clayton
28
Esas cosas existen en Clojure para la interoperabilidad con Java, pero las clases y los objetos claramente no son características principales de Clojure. No crea clases y diseña su proyecto de una manera OO si va a programar en Clojure.
Jesper
>> "que el rendimiento". El problema es: lo que sucede cuando, en el fondo de un proyecto, descubre que su rendimiento es deficiente, y no se debe a una pequeña parte (que ya había planeado convertir a Java por esa misma razón). Si bien no pretendo decir aquí "no use clojure - punto ...", debería quedar claro que clojure es un riesgo mayor en el ámbito del rendimiento. Hay muchas oportunidades para el código de nivel de aplicación para las cuales eso no importa: pero también muchas bases de código intensivas en framework / multiproceso / procesamiento donde eso sería una responsabilidad.
StephenBoesch
@javadba La idea de que clojure es malo para el código multiproceso de bajo nivel parece bastante arbitraria. Clojure está diseñado de tal manera que los errores de programación de subprocesos múltiples son muy difíciles de cometer. Los datos inmutables y las características de STM que son fundamentales para el lenguaje clojure son algo que no está disponible en el núcleo de Scala, y hacen que sea mucho menos probable que un programador inserte accidentalmente una condición de carrera o un punto muerto en su código. Seguramente esto es más valioso que los pocos ms de tiempo de ejecución que puede obtener de un lenguaje escrito estáticamente como Scala o Java.
nben
"Seguramente esto es más valioso que unos pocos ms de tiempo de ejecución" .. Eso depende de la escala de los datos. unos pocos ms están bien para algunos registros. multiplicar por cientos de millones ..
StephenBoesch
16
  1. Idiomatic Scala es más rápido que el idiomático Clojure, y seguirá siéndolo.
  2. Tanto Scala como Clojure se sientan fácilmente sobre Java. Ninguno se sienta bien debajo de él.

Si su código es crítico en el tiempo o en el espacio en todo momento, apéguese a Java. Pero no lo es, incluso si crees que lo es.

The Computer Language Benchmark Game arroja poca luz sobre los verdaderos costos de recursos de Clojure. No se emplean estructuras de datos de Clojure. No aparecen abstracciones funcionales y de secuencia.

Clojure puede parecer simple. No lo es, pero es expresivo. Puede funcionar cinco veces más lento que Java, pero la fuente es cinco veces más pequeña (YMMV). Para la mayoría de las aplicaciones, esta es una gran ventaja. Pero para algunos, y para algunas partes de muchos otros, es una pérdida devastadora.

Con la experiencia del lenguaje Clojure, creo que es posible decir de antemano si su problema se dividirá limpiamente en una parte que puede expresarse de manera sucinta y adecuada (en términos de rendimiento) en Clojure y una parte que debe hacerse en Java.

  • Puede optar por Scala lite: escribir modismos de Java en Scala. Obtendrá algo de brevedad, una sintaxis más agradable a la vista y un sistema de tipos coherente aunque complejo.
  • Clojure lite no existe: escribir modismos de Java en Clojure no tiene sentido. Todo lo que obtendrá es un Java lento que es difícil de entender porque atraviesa la veta de los modismos utilizados para expresarlo.

Se ha dicho que Scala es Java hecho correctamente . Clojure no se parece en nada a Java. Se podría decir que Lisp está bien hecho , una afirmación audaz, algunos dirían absurda, que puede resultar cierta.

Miniatura
fuente
4
Esta respuesta arroja buena luz sobre las verdaderas diferencias y fortalezas / debilidades de los dos. No está escrito en forma scala- ni clojure- apologista sino más bien en forma de veracidad.
StephenBoesch
15

Las estadísticas producidas por el " Computer Language Benchmark Game " son las mejores que probablemente encontrarás.

Son detallados y puedes comparar muchos idiomas. El problema es que no cubren Clojure :(

Dicho esto, es bastante fácil enviar cualquier cosa, todo es de código abierto.

Las estadísticas dicen que Scala es bastante rápido.

Bill K
fuente
9
Ahí tienes. 2-25 veces más lento que Java, 2-30 veces más memoria y el tamaño del código es generalmente más grande que Java. Parece que es comparable a Python, donde Scala está muy cerca de Java. Yo diría que Scala es un ganador bastante claro y Clojure es significativamente más lento, a menos que la prueba de Clojure esté mal escrita.
Bill K
2
Parece que el punto de referencia cubre Clojure ahora (el comentario de OP tiene un año). Y los resultados no son alentadores. Scala es el camino a seguir.
Martin
4
Los comentarios anteriores están algo desactualizados: a mediados de 2012, Clojure ha cerrado la brecha sustancialmente, ahora solo es aproximadamente 2x Java en promedio.
mikera
9

Sobre la interoperabilidad, no puedo hablar por Clojure, pero esperaría que estuviera en una situación similar a Scala.

Es trivialmente fácil llamar a Java desde Scala.

Es fácil llamar a Scala desde Java siempre que adapte su API externa a los puntos comunes entre Scala y Java. Por ejemplo, un objeto Scala se usa de alguna manera como métodos estáticos en Java, pero no es lo mismo. Las clases de Scala pueden compilarse en varias clases con nombres que parecen divertidos en Java.

No querrás mezclar y combinar mucho. El componente de construcción en Scala o Clojure que usa muchas bibliotecas de Java es muy factible. Por supuesto, puede llamar a este componente desde Java, pero lo que no querrá hacer es intentar consumir una API de Scala destinada a los programas de Scala de Java.

SVN afirma ser "CVS bien hecho". En mi opinión, Scala es Java bien hecho.

Kevin Peterson
fuente
19
entonces clojure es git?
Ron
1
@Ron jaja, pensé exactamente lo mismo.
KoW
2
En realidad, las colecciones de Clojure son git-ish
Joe Lehmann
2

La edición de noviembre de 2010 de PragPub analiza la interoperabilidad Clojure-Java. Llamar a los métodos de Java es sencillo, pero extender las clases / interfaces de Java es bastante diferente.

Scala, por otro lado, está mucho más cerca de Java. La interoperabilidad Scala-Java se detalla en http://www.codecommit.com/blog/java/interop-between-java-and-scala

Llamar código Java y extender clases / interfaces Java funciona de la misma manera que llamar código Scala. Algunos puntos débiles pueden ser algunos casos extremos de lidiar con los genéricos de Java, porque el sistema de tipos de Scala es mucho más fuerte que el de Java. La creación de captadores y definidores siguiendo la convención de Java Bean requiere una anotación .

Llamar a Scala desde Java es la mayoría de las veces sencillo, pero, por ejemplo, los objetos complementarios de Scala requieren saber cómo se compilan en código de bytes. Además, el uso de características con métodos no abstractos de Java debería ser complicado, y llamar a métodos con caracteres especiales requeriría saber cómo están codificados en el código de bytes.

Esko Luontola
fuente
1

Ahora (a partir de mayo de 2010) vale la pena buscar en la última rama 1.2 de Clojure; esto incluye una gran cantidad de soporte adicional para tipos primitivos y tipado estático (a través de varios protocolos y sugerencias de tipo).

Tengo entendido que puede usar estas funciones cuando las necesite para obtener una velocidad equivalente a escribir exactamente el mismo código en Java puro.

mikera
fuente
2
Y al mismo tiempo, la @specializedtécnica del próximo Scala 2.8 traerá una mejora análoga a las bibliotecas de Scala. Y como función de lenguaje, está disponible para todo el código, no solo para la biblioteca estándar.
Randall Schulz