kamulog

xamarin.formsのネタなど

スタートアップトレース (Startup Tracing / Profiled AOT) を使ってXamarin.Androidの起動速度を向上させる

この記事はXamarin Advent Calendar 2020の9日目の記事です。

Xamarin.Androidの起動が遅いという問題が長年ありましたが、最近はスタートアップトレースという機能である程度改善できるようになっています。 この機能は、残念ながら公式ドキュメントに記載されておらず、公式ブログに2件ほど記事がある程度で、あまり浸透してないのかもと思い、日本語の記事を書いてみることにしました。

このスタートアップトレース機能は2種類の方法があり、一つはデフォルトのプロファイルを使用する方法で、もう一つがカスタムのプロファイルを生成してそれを適用する方法です。

まずはどれくらいの効果があるのかを、私の個人開発アプリ「Fithor」で比較してみました。

ライブラリの使用状況はこんな感じです。

f:id:kamusoft:20201128171008p:plain

比較動画

youtu.be

結果

スタートアップトレース 起動時間 aabサイズ
なし 6.42s 39.4MB
デフォルト 6.90s 61.4MB
カスタム 6.00s 66.7MB

うむ、微妙ですね。 実は比較とかする以前に初めてスタートアップトレースを有効にした時はもっと劇的に早くなったと思ったんですが、 まぁプロジェクト構成もその時と比べて変わったし、そういう影響なんだろうと思います。

スタートアップトレースOFFよりスタートアップトレースONのデフォルトプロファイルの方が遅くなっちゃってますが 、これは誤差の範囲だと思います。 というより、この結果で重要なことは、スタートアップトレースはただ有効にするだけ(デフォルトプロファイルを使うだけ)では ほとんど効果が出ない場合があるってことだと思います。

カスタムプロファイルを使うことで1秒弱縮まってます。起動速度の1秒はかなり大きいのでこれは是非有効にすべきだと思います。

カスタムプロファイルの作成方法

Androidのプロジェクトのフォルダに移動し以下のコマンドを実行してビルドします。

msbuild /t:BuildAndStartAotProfiling

この時、シミュレータや接続している実機は1つだけの状態にする必要があります。 使わないシミュレータや実機は外しておきましょう。

ビルドが終わりアプリが起動すると完了です。

次に以下のコマンドを実行してプロファイルを生成します。

msbuild /t:FinishAotProfiling xxxxx.csproj  

以下のようなメッセージが表示されれば完了です。

  Summary:
    Modules:         51
    Types:        2,261
    Methods:      9,125
  Going to write the profile to 'custom.aprof'

これでプロジェクトにcustom.aprofが生成されます。

カスタムプロファイルの有効化

まずはスタートアップトレースを有効にします。以下 VS for Mac の例です。

f:id:kamusoft:20201128172347p:plain

カスタムプロファイルを使う設定はUIには存在しないのでcsprojを直接開いてリリースビルド構成のところに 以下の項目を追加します。

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
...
    <AndroidUseDefaultAotProfile>false</AndroidUseDefaultAotProfile>
</PropertyGroup>

同じくcsprojに以下のように、カスタムプロファイルをプロジェクトに追加します。

<ItemGroup>  
    <AndroidAotProfile Include="$(MSBuildThisFileDirectory)custom.aprof" />
</ItemGroup>  

これで設定完了です。

ビルドした際にログに以下のように表示されればカスタムプロファイルは適用されています。

[aot-compiler stdout] Using profile data file '/Users/xxxxx/custom.aprof'

注意事項

カスタムプロファイルを生成するのに adb と シミュレータまたは実機が必要になるため、 この工程はCIには組み込めないと思います。 ライブラリや起動ページの構成なんかが大きく変わらない限りは毎回は生成する必要ないと思いますが、 定期的にローカルで実行して生成し直す方が良さそうです。

おわりに

Xamarin.Android (Xamarin.Forms Android) で起動時間を1秒でも縮めたい場合は是非スタートアップトレース カスタムプロファイルを使いましょう!

参考