CustomScript

ページ

2020年4月5日日曜日

.NET Framework の ネイティブイメージコンパイル

  • .NET Framework
ひさびさの技術情報です。

「ネイティブ イメージを使って .NET デスクトップ アプリを最適化する」 というものがあったので試してみました。

これまで .NET Framework のネイティブコンパイラといえば NGEN がありました。 ネイティブコードにコンパイルしたものをシステムのキャッシュに登録し、実行時にそのキャッシュを使うことで高速化する仕組みです。 ですが、扱いづらい部分もあって、NGENツールでコンパイルしてシステムのキャッシュに登録するという処理が必要なためにインストール時に処理ができるMSIパッケージ等でしか実用できませんでした。 あと、フレームワークが更新されるとキャッシュが無効になるという問題もありました。

新しいネイティブイメージコンパイラはそのあたりの懸案が解消されます。 ビルド時にネイティブコンパイルも行い、実行ファイルの中にネイディブコードを埋め込みます。このため、ZIPパッケージやストアアプリでも恩恵を受けることができます。 欠点としては、アーキテクチャをx86,x64どちらかに限定してビルドしないといけないこと、ネイティブコードの分実行ファイルのサイズが大きくなること、でしょうか。

試してみた


試しにNeeViewをネイティブイメージコンパイラに対応させて検証してみました。起動からウィンドウ表示までの時間を複数回計測します。
# Default NeeView.exe size : 2,552KB App.MainWndow.Loaded.Done: 1735ms App.MainWndow.Loaded.Done: 1697ms App.MainWndow.Loaded.Done: 1728ms
# with Native Image Compiler NeeView.exe size : 5,420KB App.MainWndow.Loaded.Done: 1070ms App.MainWndow.Loaded.Done: 1028ms App.MainWndow.Loaded.Done: 1047ms
ファイルサイズは倍増しましたが、起動速度は3割ほど早くなりました。結構効いてますね。 数回起動してコンパイル済みキャッシュが効いている状態なので、初回起動時ならこの差はもっと大きくなると予想されます。

導入の注意点


「ネイティブ イメージを使って .NET デスクトップ アプリを最適化する」 を参照して導入すればいいのですが、いくつか注意点があります。
  • PowerShellでNugetインストールするとあるが、そのPowershellはパッケージマネージャーコンソールのことである(ツール > NuGetパッケージマネージャー > パッケージマネージャーコンソール)。通常のNugetパッケージのようにプロジェクトのNugetパッケージ管理からインストールしても良い。実行ファイルのプロジェクトだけで良い。
  • デフォルトのビルドログは省略されているので、オプションの「ビルド/実行」でビルド出力/ログを最小以上にする。これで "Native image ~ generated successfully" が確認できる。
  • VisualStudioから実行するとネイティブコンパイルされてないバイナリに置き換わってしまう?

3 件のコメント:

  1. とおりすがりですが、非常に興味深い投稿です。
    ネイティブコードが埋め込まれたexeには中間ILコードは無く、逆コンパイル不可なのでしょうか?

    返信削除
    返信
    1. exeにはネイティブコードとMSILコード両方とも入っています。これによって、このネイディブコードが動作できないクライアントではILコードを使用した従来の動作になるようです。詳細はこの記事からリンクされているMSのページを参照してください。
      逆コンパイルは試したことががないので不明です。

      削除
    2. なるほど。
      ILコードを省けると難読化を考えなくていいので理想なのですが。
      逆コンパイルがあっさりできてしまうのが気分的に嫌なんですよ。

      削除