performance clojure startup

performance - Rendimiento de inicio de la aplicación Clojure



startup (3)

He escrito algunas pequeñas aplicaciones de utilidad en Clojure que compilo en archivos JAR ejecutables independientes ("uberjars") utilizando Maven y el complemento de la cortina de Maven. 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).

Descubrí que las aplicaciones Clojure tardan varios segundos en iniciarse, 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á sobre la marcha compilando algo del código en la biblioteca clojure.core ya que hay código fuente (archivos .clj ) 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 el tiempo de inicio (y no saben ni les importa que la aplicación esté escrita en Clojure o Java o Foobar).


En el sitio de Clojure hay una buena descripción de la compilación de AOT . Esto ya eliminará un poco de tiempo de inicio.

Edición : se han realizado algunos esfuerzos para ejecutar programas de Clojure en una JVM persistente, lo que reduce el tiempo de inicio. Búsqueda jark + jvm. Sin embargo, el sitio parece haber desaparecido :(


JVM (al menos el HotSpot de Oracle) hace que sea muy difícil reducir el tiempo de inicio. No carga en la memoria todas las clases y métodos del programa, solo carga los 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 algunas funciones y el programa Java se inicia rápidamente. Además, HotSpot ni siquiera compila estas pocas funciones, sino que utiliza la compilación JIT (y otras optimizaciones) para el código, que se ejecuta repetidamente. No hay razón para dedicar tiempo a compilar funciones que se ejecutarán solo una vez, por ejemplo, casi todos los métodos de inicio, y HotSpot no.

Entonces, ¿qué pasa con Clojure? No creo que te gustaría volver a escribir el núcleo de Clojure para agregar una funcionalidad similar. Sin embargo, puede utilizar el mismo enfoque dentro de su código de Clojure. Usted dijo que sus utilidades usan varias bibliotecas, que pueden ralentizar el inicio. Por lo tanto, cargue las bibliotecas con pereza tanto como pueda. Por ejemplo, puede excluir :use opción de su definición de espacio de nombres y llame al use explícito en sus funciones principales. Esto no reducirá el tiempo total, pero cambiará el dalay al momento, cuando no sea tan apreciable. Incluso puede escribir una pequeña parte de su programa en Java y llamar al código de Clojure solo cuando sea necesario.


Por supuesto, también existe el argumento JVM de java -client para mejorar el rendimiento de inicio de JVM. Esta pregunta de SO entra en algunos detalles sobre este tema.