PackageCompiler.jl の README によるとついに Plots.jl がコンパイルできるようになったらしいので試してみました。
環境
各パッケージのバージョンは最後に記載の Manifest.toml, Project.toml をご覧ください。 Unix系のOSならばこれらのファイルを使って今回の私の結果を再現できると思います。
Plots.jl をコンパイルする
Windows の場合は管理者モードで Julia を起動して ImageMagick
も入れる。
macOS の場合は事前に gcc
を入れておく。
import Pkg Pkg.add.(["PackageCompiler", "Plots"]) # mac の場合はこの後に build しておくと良さそうです。 using PackageCompiler compile_package("Plots", force=false)
無事に終了すると次のように出ます。
All done ┌ Info: Not replacing system image. └ You can start julia with `julia -J /home/goropikari/.julia/packages/PackageCompiler/oT98U/sysimg/sys.so` at a posix shell to load the compiled files. "/home/goropikari/.julia/packages/PackageCompiler/oT98U/sysimg/sys.so"
指示に従い
julia -J /home/goropikari/.julia/packages/PackageCompiler/oT98U/sysimg/sys.so
で Julia を起動します。こうすると Plots をコンパイルした system image を読み込んできます。 引数取らずに普通に Julia を起動するとデフォルトの system image で起動します。
スピードを比較
以下のコードを3回実行し、その実行時間を計測しました。
julia> @time begin using Plots plot(rand(10)) end
加えて、PackageCompiler を使うと Plots の読み込み等は早くなりますが、Julia 本体の起動が遅くなるので Julia の起動に掛かる時間も計測しました(Linux のみ)。
Linux
Machine Spec
julia> versioninfo() Julia Version 1.1.0 Commit 80516ca202 (2019-01-21 21:24 UTC) Platform Info: OS: Linux (x86_64-pc-linux-gnu) CPU: Intel(R) Core(TM) i5-4460T CPU @ 1.90GHz WORD_SIZE: 64 LIBM: libopenlibm LLVM: libLLVM-6.0.1 (ORCJIT, haswell)
デフォルト
- コードの実行時間
31.221949 seconds 28.103826 seconds 30.471024 seconds 平均 29.932 seconds
- Julia の起動までに掛かる時間
計測方法は以下のよう。
time julia -e 'exit()'
結果
0m0.178s 0m0.182s 0m0.166s 平均 0.175 seconds
PackageCompiler
- コードの実行時間
0.003226 seconds 0.003102 seconds 0.003285 seconds 平均 0.003204 seconds
- Julia の起動までに掛かる時間
0m1.418s 0m1.405s 0m1.411s 平均 1.411 seconds
Windows 10
ArchLinux とデュアルブートしている Win7 で検証したかったのですが、そもそもコンパイルに失敗したので別機で検証しました。
Machine Spec
julia> versioninfo() Julia Version 1.1.0 Commit 80516ca202 (2019-01-21 21:24 UTC) Platform Info: OS: Windows (x86_64-w64-mingw32) CPU: Intel(R) Core(TM) i3-3110M CPU @ 2.40GHz WORD_SIZE: 64 LIBM: libopenlibm LLVM: libLLVM-6.0.1 (ORCJIT, ivybridge)
デフォルト
- コードの実行時間
44.759472 seconds 42.556326 seconds 37.836190 seconds 平均 41.717329 seconds
PackageCompiler
- コードの実行時間
2.274401 seconds 2.682438 seconds 2.648822 seconds 平均 2.535220 seconds
macOS Mojave
Machine Spec
julia> versioninfo() Julia Version 1.1.0 Commit 80516ca202 (2019-01-21 21:24 UTC) Platform Info: OS: macOS (x86_64-apple-darwin14.5.0) CPU: Intel(R) Core(TM) i7-4771 CPU @ 3.50GHz WORD_SIZE: 64 LIBM: libopenlibm LLVM: libLLVM-6.0.1 (ORCJIT, haswell)
デフォルト
- コードの実行時間
19.305938 seconds 19.382959 seconds 20.343827 seconds 平均 19.677575 seconds
- Julia の起動までに掛かる時間
0m0.172s 0m0.185s 0m0.177s 平均 0.178s
PackageCompiler
- コードの実行時間
1.168776 seconds 1.226039 seconds 1.186678 seconds 平均 1.193831 seconds
- Julia の起動までに掛かる時間
0m1.098s 0m1.117s 0m1.123s 平均 1.113s
Jupyter Notebook に Kernel を追加する
コンパイル時に force=true
にしていないとデフォルトで読み込む system image がコンパイルしたものにならないので、このままでは jupyter を使ったとき Plots の読み込みを早くすることができません。
そこでコンパイルした system image を読み込めるように kernel を追加します。
※注意: ここでは IJulia で Jupyter を入れたとします。 Anaconda 等でも同様にできると思います。
Linux
~/.local/share/jupyter/kernels
に julia-1.1
というフォルダがあるのでこれをコピーします。今回はフォルダ名を julia-1.1-plots
としました。
cp -r ~/.local/share/jupyter/kernels/julia-1.1 ~/.local/share/jupyter/kernels/julia-1.1-plots
次に julia-1.1-plots
中の kernel.json
に -J
と /home/ユーザー名/.julia/packages/PackageCompiler/oT98U/sysimg/sys.so
を以下のように追加します。
ついでに display_name
も同じだと分かりづらいので適当に変えておきましょう。
{ "display_name": "Julia 1.1.0 plot", "argv": [ "/home/ユーザー名/.local/julia/julia-1.1.0/bin/julia", "-J", "/home/ユーザー名/.julia/packages/PackageCompiler/oT98U/sysimg/sys.so", "-i", "--startup-file=yes", "--color=yes", "/home/ユーザー名/.julia/packages/IJulia/4UizY/src/kernel.jl", "{connection_file}" ], "language": "julia", "env": {}, "interrupt_mode": "signal" }
上手くいくとこのように kernel が追加されます。
Windows
C:\Users\ユーザー名\AppData\Roaming\jupyter\kernels
に julia-1.1
というフォルダがあるのでこれを複製します。今回はフォルダ名を julia-1.1-plots
としました。
次に julia-1.1-plots
中の kernel.json
に -J
と C:\\Users\\ユーザー名\\.julia\\packages\\PackageCompiler\\oT98U\\sysimg\\sys.dll
を以下のように追加します。
ついでに display_name
も同じだと分かりづらいので適当に変えておきましょう。
{ "display_name": "Julia 1.1.0 plot", "argv": [ "C:\\Users\\ユーザー名\\AppData\\Local\\Julia-1.1.0\\bin\\julia.exe", "-J", "C:\\Users\\ユーザー名\\.julia\\packages\\PackageCompiler\\oT98U\\sysimg\\sys.dll", "-i", "--startup-file=yes", "--color=yes", "C:\\Users\\ユーザー名\\.julia\\packages\\IJulia\\4UizY\\src\\kernel.jl", "{connection_file}" ], "language": "julia", "env": {}, "interrupt_mode": "message" }
上手くいくとこのように kernel が追加されます。
試しにプロットしてみましたが、どうやら Jupyter 通すと実行速度が遅くなるようです。
まとめ
単純にパッケージの読み込み・グラフの描写に掛かる時間のみに着目すると PackageCompiler を使った場合、Linux ではデフォルトよりも9342倍早くなるという結果になりました。 PackageCompiler を使った場合は Julia の起動時間が遅くなりますが、それを考慮しても21倍早くなるという結果になりました。
mac, Windows の場合ではパッケージの読み込み・グラフの描写に掛かる時間のみに着目しても16倍程度しか早くならず Linux と比べるとインパクトが少ないですが、元が元なのでやって損はないです。
Julia の起動が遅いのは地味にストレスなのでプロットするか否かに応じて system image を変える方法で運用していくのが良いかと思います。毎回 Plots.jl を読み込むと言うなら
compile_package("Plots", force=true)
とするのが楽です。