Подтвердить что ты не робот

Clojure производительность запуска приложения

Я написал несколько небольших служебных приложений в Clojure, которые я компилирую в автономные исполняемые JAR файлы ( "uberjars" ), используя Maven и maven-shade-plugin. Эти uberjars содержат распакованные версии clojure.jar и других библиотек (т.е.: commons-cli), от которых зависит приложение. Они удобны, потому что я могу отправить их клиенту, не требуя, чтобы клиент установил Clojure (у всех клиентов уже установлен JRE).

Я обнаружил, что приложения Clojure занимают несколько секунд для запуска, тогда как аналогичные приложения, написанные на Java, начинаются в подсеансах на тех же машинах (время, например, для отображения сообщения об использовании).

Я подозреваю, что это потому, что Clojure находится на лету, компилируя некоторый код в библиотеке clojure.core, поскольку в файле clojure.jar есть исходный код (.clj files).

Есть ли способ прекомпилировать этот исходный код? Можно ли сделать что-нибудь еще, чтобы ускорить запуск? Я слышал жалобы от клиентов о том, сколько времени занимает стартап (и они не знают или не заботятся о том, чтобы приложение было написано в Clojure или Java или Foobar).

4b9b3361

Ответ 1

JVM (по крайней мере, Oracle HotSpot) делает очень сложной задачу сократить время запуска. Он не загружает в память все программные классы и методы, он загружает только те ресурсы, которые ему нужны прямо сейчас. Существует не так много кода, чтобы показать сообщение об использовании или что-то в этом роде, поэтому на самом деле загружаются только несколько функций, и программа Java запускается быстро. Более того, HotSpot даже не компилирует эти несколько функций - он использует JIT-компиляцию (и другую оптимизацию) для кода, который выполняется повторно. Нет причин тратить время на компиляцию функций, которые будут выполняться только один раз, например. почти все методы запуска, а HotSpot - нет.

Итак, как насчет Clojure? Я не думаю, что вы хотели бы переписать ядро ​​Clojure, чтобы добавить аналогичную функциональность. Тем не менее, вы можете использовать такой же подход внутри своего кода Clojure. Вы сказали, что ваши утилиты используют несколько библиотек, которые могут замедлить запуск. Итак, загружать библиотеки лениво сколько угодно. Например, вы можете исключить опцию :use из определения пространства имен и вместо этого вызывать явно use в своих основных функциях. Это не уменьшит общее время, но будет сдвинуть dalay до момента, когда это будет не так заметно. Вы даже можете записать небольшую часть своей программы на Java и вызвать код Clojure только тогда, когда это действительно необходимо.

Ответ 2

На сайте Clojure есть хорошее описание компиляция AOT. Это уже сократит время запуска.

Изменить: были предприняты некоторые попытки запустить программы Clojure на постоянной JVM, что сокращает время запуска. Взгляд jark + jvm. Однако, похоже, сайт был удален: (

Ответ 3

Конечно, существует также аргумент JVM java -client для повышения производительности запуска JVM. Этот вопрос SO подробно освещает эту тему.