Project環境を作るメリット

3 Oct 2021

(src=https://pixabay.com/photos/agriculture-rice-plantation-thailand-1807581/)

パッケージ管理システム

juliaのパッケージ管理システムPkg.jlは、Project.tomlとManifest.tomlというTOML(Tom's Opbvious, Minimal Language)で書かれたテキスト形式の設定ファイルを使って、インストールされたパッケージの情報・依存関係を管理しています。[1]

通常これらのファイルは以下の場所に作成されます。

  • windowsの場合: %USERPROFILE%.julia\environments\v1.x

  • linuxの場合: home/.julia/environments/v1.x

xのところには実際のバージョン番号が入ります。

juliaのreplを立ち上げたときは、ここを参照するわけですが、 それとは個別のProject環境を作って、別のProject.tomlおよびManifest.tomlを参照することもできます。

今回は わざわざそのようなことをするメリットについてまとめておきます。

[1] 二つのtomlファイルの中身の詳細については、今回は割愛します。

Project環境の作り方

メリットについて述べる前にProject環境の作り方を整理しておきます。 たとえば、plotsというディレクトリで作業しているとします。 以下のようなコードを実行すると、Plots.jlをインストールしたプロジェクト環境を作成できます。

PS~~~\plots> julia 
julia>]
(@v1.7) pkg> activate .
(plots) pkg> add Plots

juliaのreplを立ち上げて、パッケージモードに移行します。 activate .と打つと現在のディレクトリをプロジェクト環境として参照します。 ここはプロジェクトファイルをおいてあるディレクトリを直接書いてもかまいません。 activateした後に、必要なパッケージをaddするとproject.tomlとmanifest.tomlが自動生成されます。

一度プロジェクトファイルを作ったあとであれば、--projectオプションをつけて、repl起動時にプロジェクト環境を指定することもできます。

PS~~~\plots>julia --project=.
julia>]
(plots) pkg>

パッケージダウングレード問題を解消

黒木玄さんのtwitterを引用しましたが、本当にその通りで 新しいパッケージをインストールしたり、アップデートをかけただけなのに別のパッケージのバージョンが下がってしまうということは良く起こります。これはあるパッケージが指定するバージョンと、別のパッケージが指定するバージョンの上限が合わないためです。 この問題は、ボトルネックになっているパッケージのバージョンアップで解消されるのですが、それをいちいち待っていられないのが人情というものです。

個別にプロジェクト環境を作って、 必要最小限のパッケージだけを使うようにしておけば、パッケージのダウングレードのリスクを最小化できます。

他人のパッケージ環境をコピーできる。

juliaの色々なパッケージのチュートリアル等で、以下のようなコマンドを求められることもあるでしょう。

julia>import Pkg
julia>Pkg.activate(".")
julia>Pkg.instantiate()

これをすると、現在ディレクトリのプロジェクト環境を参照して、そこに記載されているバージョンのパッケージをインストールできます。 チュートリアルを作った人と同じバージョンのパッケージを使用できるので、コードを実行できないリスクが低くなります。

Visual Studio Code(VS Code)でのメリット

次はVS Codeで個別のプロジェクト環境を準備するメリットをまとめておきます。 VS Codeでjuliaのreplを立ち上げると、プロジェクトファイルがある場合には自動的にそのファイルを認識するようになっています。

Language Server Protocol(LSP)のIndexingが早くなる。

VS Codeでコードを書くときは、コードの補完機能が非常に役に立ちます。 ただし、このコードを補完機能を使うには、LSPがプロジェクト環境にあるパッケージを読み込んで、 補完機能を使えるようにIndexingをしているようです。 デフォルトのプロジェクト環境にたくさんのパッケージを入れているとこのIndexingの行程が何時間かかっても終わらない事態になってしまいます。VS Codeを快適に使うには、 個別のプロジェクト環境を作るのは大前提と言っても良いかもしれません。

System imageを作ることができる。

VS CodeではCtrl+Shift+B + Enterコマンドを打つとプロジェクトファイルにあるパッケージのコンパイル済みイメージを作ることができます。[2]

コンパイル後にはJuliaSysimage.dllというファイルが作られていることがわかります。 コンパイルには数分かかりますが、一度システムイメージを作ると次にreplを立ち上げるときには 自動でシステムイメージを認識してくれるので、パッケージの読み込みがものすごく早くなります。

[2] システムイメージの構築には、PackageCompiler.jlを使う方法もありますが、こちらの方が圧倒的に簡単です。

TTFP(time to first plot)

ここでは、TTFP(time to first plot)というjulia界隈でよく使われるベンチマークをやってみます。 Plots.jlというのは、比較的よく使われる可視化パッケージですが、usingにかかる時間は非常に長いことで知られています。

最初にシステムイメージを読み込まない状態で、Plots.jlをインポートして適当なプロットを実行します。

PS C:\folder> julia --project -e '@time using Plots;plot(rand(10))'
  4.123728 seconds (8.06 M allocations: 564.466 MiB, 3.64% gc time, 0.23% compilation time)

このときの実行時間はおよそ4秒です。以前に比べればかなり早くなった方ですが、 まだ秒単位で時間がかかります。(以前は数十秒かかっていた。)

システムイメージを読み込んだreplを起動するには-Jオプションを使います。

PS C:\folder> julia -J JuliaSysimage.dll --project -e '@time using Plots;plot(rand(10))'  
  0.007352 seconds (1.33 k allocations: 86.109 KiB, 38.49% compilation time)

読み込み時間がm秒オーダーになりました。これでいわゆるTTFPのストレスは改善されます。

このシステムイメージを構築する方式の欠点は、

  • システムイメージの容量が数100MBと重いこと

  • プロジェクトファイルが更新されるとシステムイメージを読み込めずreplが立ち上がらないこと

です。

こうした欠点を念頭に置けば、うまく運用できるようになるかと思います。

まとめ

Project環境をつくるメリットをまとめます。

  • パッケージ更新時のダウングレードの問題を解消できる。

  • Pkg.instantiate()で他人と同じ環境を構築できる。

  • VS CodeでLSPのIndexingが早くなる。

  • VS CodeでProject専用のSystem Imageを作ることができる。パッケージの読み込みが爆速になる。

めでたしめでたし