昨日はGradleをちょっと使ってみたわけですが、元がGroovyだからかどうかはわかりませんけど、とにかく重い印象があります。やっぱり、こういうのって1回きりの使い捨てより、常駐型でないと厳しいですよね。
というわけで、ここでGradleが用意しているのがDaemonです。
http://www.gradle.org/docs/current/userguide/gradle_daemon.html
http://gradle.monochromeroad.com/docs/userguide/gradle_daemon.html
まあ、文章中に「experimental」と書かれているように、まだ試験的サポートのようですが。
とはいえ、効果は明らかにあるようなので、使っていってみましょう。今回使うGradleプロジェクトのスケープゴートは、最初に用意したJavaの「Hello World」プロジェクトです。
こんなやつですね。
public class HelloGradle { public static void main(String[] args) { System.out.println("Hello World"); } }
Gradle Daemonを使用する
けっこう簡単で、gradleコマンドの引数に「--daemon」を付けるだけです。
$ gradle --daemon run :compileJava :processResources UP-TO-DATE :classes :run Hello World BUILD SUCCESSFUL Total time: 8.931 secs
この時、バックグラウンドで
org.gradle.launcher.daemon.bootstrap.GradleDaemon
というMainクラス名でJavaプロセスが起動していることが確認できます。psなどで見るとよいでしょう。
ここで、「Hello World」を「Hello Gradle」に変えて実行してみます。
$ gradle --daemon run :compileJava :processResources UP-TO-DATE :classes :run Hello Gradle BUILD SUCCESSFUL Total time: 1.562 secs
初回は9秒かかっていたものが、一気に2秒弱まで短くなりましたね。なお、Daemonなしで同じ操作をすると、両方とも7秒程度の実行時間を要しました。
かなり高速になっていることが確認できます。なかなか便利ですね。
が、残念ながらScalaにはあまり効果はありませんでした…Groovyに対して適用した場合も、Javaよりは速度が落ちます。将来的にはGroovyやScalaのコンパイラの起動を維持したいと言っているので、今は仕方がないのでしょうね。
以下の点には、注意が必要かもしれません。
- 既存のDaemonプロセスが、なにか別の処理をしている場合は新たなDaemonプロセスを起動する
- JavaVMの環境ごとに、起動するDaemonプロセスは分かれる(*1)
- JavaVMの引数(ヒープの設定やファイルのエンコーディングなどのシステムプロパティなど)を変更しても、それ毎にDaemonが起動する(*2)
- Daemonプロセスは、3時間のアイドル状態が続くと有効期限切れとなる
*1 使用するJavaを変えると、それ毎に起動するよってことなんでしょう
*2 GradleプロジェクトでJavaVMの設定を変えたりすると、やっぱりそれ毎に起動するよってことなんでしょう
Gradle Daemonのログ出力先
なんか、$HOME/.gradle/daemon配下にできます。
$ ll ~/.gradle/daemon/1.1/ 合計 296 drwxrwxr-x 2 xxxxx xxxxx 4096 Aug 6 16:38 ./ drwxrwxr-x 3 xxxxx xxxxx 4096 Aug 5 22:34 ../ -rw-rw-r-- 1 xxxxx xxxxx 87515 Aug 5 22:35 daemon-19562.out.log -rw-rw-r-- 1 xxxxx xxxxx 41735 Aug 6 15:47 daemon-21956.out.log -rw-rw-r-- 1 xxxxx xxxxx 64493 Aug 6 15:50 daemon-22109.out.log -rw-rw-r-- 1 xxxxx xxxxx 30329 Aug 6 16:34 daemon-22854.out.log -rw-rw-r-- 1 xxxxx xxxxx 50267 Aug 6 16:40 daemon-23100.out.log -rw-rw-r-- 1 xxxxx xxxxx 1596 Aug 6 16:40 registry.bin -rw-rw-r-- 1 xxxxx xxxxx 2 Aug 6 16:40 registry.bin.lock
Gradle Daemonの停止方法
gradleコマンドの引数に、「--stop」を付与します。
$ gradle --stop Stopping daemon(s). Gradle daemon stopped.
文字通り、停止します。
Gradle Daemonを使用しないようにする
gradleコマンドの引数に、「--no-daemon」を付与します。
$ gradle --no-daemon run
まあ、すでにDaemonプロセスがあっても使用しないので、遅くなるといえば遅くなります。
gradle.propertiesでDaemonを使用することを設定する
gradleコマンドで、「--daemon」を付与せずともDaemonを使用するようにすることを、gradle.propertiesというファイルを用意することで設定可能です。
http://www.gradle.org/docs/current/userguide/tutorial_this_and_that.html#sec:gradle_properties_and_system_properties
gradle.propertiesは
のいずれかに配置するそうです。
ここでは、プロジェクトディレクトリ直下に作成してみます。
gradle.properties
org.gradle.daemon=true
これだけで、そのプロジェクト内で使用するgradleコマンドはDaemonを使用するようになります。
ちなみに、配置先の2つ目である「Gradleのユーザホームディレクトリ」というのは
$HOME/.gradle
を指します。このディレクトリ直下に、gradle.propertiesを配置しておけばOKです。
あと、-Dシステムプロパティを使用することでも指定可能です。
$ gradle -Dorg.gradle.daemon=true run
こっちはあまり使わないでしょうけど…。