2011-05-16 25 views
19

He escrito algunas aplicaciones de utilidad pequeñas en Clojure que compilo en archivos ejecutables JAR ("uberjars") usando Maven y maven-shade-plugin. Estos uberjars contienen versiones desempaquetadas de clojure.jar y otras bibliotecas (es decir, commons-cli) de las que depende la aplicación. Son convenientes porque puedo enviarlos a un cliente sin requerir que el cliente instale Clojure (todos los clientes ya tienen el JRE instalado).Clojure application startup performance

He encontrado que las aplicaciones Clojure tardan varios segundos en arrancar, mientras que las aplicaciones similares escritas en Java comienzan en segundos en las mismas máquinas (tiempo para mostrar un mensaje de uso, por ejemplo).

Sospecho que es porque Clojure está compilando algo del código en la biblioteca clojure.core ya que hay código fuente (.clj archivos) en el archivo clojure.jar.

¿Hay alguna manera de precompilar este código fuente? ¿Se puede hacer algo más para acelerar el rendimiento de inicio? He escuchado quejas de los clientes sobre cuánto tiempo lleva la puesta en marcha (y no saben o no les importa si la aplicación está escrita en Clojure o Java o Foobar).

+0

Vea también http://blog.ndk.io/solving-clojure-boot-time.html y http://dev.clojure.org/display/design/Improving+Clojure+Start+Time – Vadzim

Respuesta

4

JVM (al menos de HotSpot Oracle) hace algo muy difícil de reducir el tiempo de puesta en marcha. No carga a la memoria clases y métodos, todos ellos del programa, se carga únicos recursos que necesita ahora. No hay tantos códigos necesarios para mostrar un mensaje de uso o algo así, por lo que solo se cargan pocas funciones y el programa Java se inicia rápidamente. Además, HotSpot ni siquiera compila estas pocas funciones: que utiliza la compilación JIT (y la optimización de otros) para el código, que se ejecuta repetidamente. no hay razón para pasar el tiempo para compilar funciones que serán ejecutadas una sola vez, por ejemplo, casi todos los métodos de inicio, y HotSpot no.

Entonces, ¿qué hay de Clojure? No creo que le gustaría reescribir el núcleo de Clojure para agregar una funcionalidad similar. Sin embargo, puede usar el mismo enfoque dentro de su código Clojure. Dijiste que tus utilidades usan varias bibliotecas, que pueden ralentizar el inicio. Por lo tanto, cargue las bibliotecas perezosamente tanto como pueda. Por ejemplo, puede excluir la opción :use de su definición de espacio de nombres y llamar explícitamente a use en sus funciones principales. Esto no reducirá el tiempo total, pero va a shift dalay al momento, cuando no es tan apreciable. Incluso puedes escribir una pequeña parte de tu programa en Java y llamar al código de Clojure solo cuando realmente se necesita.

+0

Hola, la solución mencionada sin duda conduciría a mejoras en el rendimiento, pero ¿a qué costo? ! La buena noticia es que en Clojure 1.3, hay una función experimental (por desgracia, "temporalmente desactivado", tal como está escrito en una confirmación reciente en github), cuyo propósito es habilitar la "carga diferida" de los compilados fns. –

3

En el sitio de Clojure hay una bonita descripción de AOT compilation. Esto ya reducirá el tiempo de inicio.

Editar: se han hecho algunos esfuerzos para ejecutar programas Clojure en una JVM persistente, reduciendo así el tiempo de inicio. Look-up jark + jvm. Sin embargo, el sitio parece haber disapeared :(

+0

Ya lo hago AOT con mi propio código y solo incluye los archivos '.class' en el JAR, pero parece que el clojure.core debe incluir algún código fuente que se cumpla cuando se inicie la aplicación, a menos que esté fuera de la base y el inicio lento sea debido a alguna otra causa ¿Sugirió la reconstrucción de clojure.jar con AOT? – Ralph

+0

No se preocupe, aunque clojure.jar tiene algunos archivos .clj, también tiene los archivos .class correspondientes. El inicio lento se debe principalmente al tiempo de inicio de JVM, cada vez que ejecuta su utilidad Clojure. –

+1

"El inicio lento se debe principalmente al tiempo de inicio de la JVM, cada vez que ejecuta su utilidad Clojure". - si eso es cierto, ¿por qué las aplicaciones Java comienzan en menos de un segundo (Macbook Pro 2.66 GHz Core i7, 9GB RAM, OsX 10.6.7)? – Ralph

1

Por supuesto, también existe el argumento JVM -client Java JVM para mejorar la puesta en marcha de rendimiento. Este SO question entra en detalles sobre este tema.