この記事は RevComm Advent Calendar 2022 の 14 日目の記事です。
はじめに
こんにちは。株式会社 RevComm でモバイルアプリを開発している長尾です。 普段は MiiTel Phone Mobile の機能開発やメンテナンスを行っています。
さて、アプリをリリースした後もユーザーさんに快適に使用してもらうためには、アプリのパフォーマンスを定期的に計測し、アプリが軽快に動作しているかを確認し続けることが重要です。
本記事では、iOS アプリのパフォーマンスを計測する方法について、まとめています。
iOS アプリのパフォーマンスを測定するためのツール
iOS アプリのパフォーマンスを計測する方法として以下の三つのツールを紹介します。いずれのツールも Xcode をインストールすれば追加でツールをインストールする必要はなく、すぐに使い始めることができます。
- Debug Navigator
- Instruments
- XCTest metrics
Debug Navigator
Xcode でデバッガを接続しているときに自動で立ち上がっている画面です。 メモリ、CPU、消費電力やネットワークなどの使用状況が UI に表示されます。デバッグ中に簡易的にパフォーマンスを確認するのに便利です。コード作成中に、何らかのミスで循環参照になっているなどして、無限にメモリを消費してしまうような状況になっていることがあります。そのようなケースでは、メモリの使用状況のグラフを見ると、状況が一目で分かります。デバッガを接続している際は特に設定もなく使用可能なので、とりあえず何か起こってないか確認したいときに使用するツールだと思います。
Instruments
測定したいメトリクスをカスタマイズでき、測定できるメトリクスの種類も豊富です。測定したい項目の選択はテンプレートとして保存することができ、よく測定する項目をさまざまなシーンで容易に測定することができます。
XCTest metrics
ユニットテストの中で、特定のメソッドに対して、パフォーマンスを測定することができます。測定できる項目は Instruments ほど多くはありませんが、経過時間、メモリ使用量、CPU 使用率、ストレージに関するメトリクスなどが測定できます。他のツールにない特徴としては、正常に完了したテストのメトリクスを baseline として、次回以降のテストにおいて baseline からの乖離を評価できます。乖離が大きくなっている場合、テストが失敗したとみなすことで、パフォーマンスの低下や予期せぬ不具合を検出することができます。
これらのツールはそれぞれ用途が異なっているので、どれが優れているというわけではありません。適材適所で使用することで、各々のツールの特徴を生かすことができます。
実際にパフォーマンスを測定してみる
では、これらのツールを用いて、アプリのパフォーマンス評価を行ってみましょう。
今回評価するアプリは、最近 Apple が公開した StableDiffusion を利用できるライブラリである ml-stable-diffusion を組み込んだ簡単なアプリです。
Debug Navigator で大まかなアプリのパフォーマンスを確認する
開発段階においては、Debug Navigator を用いて大まかなアプリのパフォーマンスを把握します。中央にある Memory のセクションを見ると、Memory Use が 2.1GBと表示されています。対象のアプリは、かなり多くのメモリを使用していることが分かります。
また、メモリを大量に使用するのは画像を生成している間のみで、画像が生成されるとメモリが解放されること (2.1 GB -> 48.6 MB) が、下記の画像の Memory Use の値やグラフの落ち込みなどから確認できます。
Instruments を使ってアプリの詳細なパフォーマンスを確認する
アプリが意図通りに動作していることがある程度確認できたので、もう少し詳細なパフォーマンスを確認していきます。 最初に挙げた三つのツールの中で、最も詳細にパフォーマンスを測ることができるツールである Instruments を使って、パフォーマンスを見ていきましょう。
ml-stable-diffusion は、CoreML を利用しています。またライブラリが要求するシステム要件も iOS16.2 以上、iPhone 12 以上となっていることから、ml-stable-diffusion を実行するために、機械学習の処理に特化したチップである Neural Engine を利用していることが推測されます。これを Instruments を使って確認してみましょう。 Xcode から Develop tools > Instruments とたどり、Instruments を起動させます。Instruments を起動させると、テンプレートを選択する画面が表示されます。 パフォーマンスを確認したいタイプのテンプレートを選択すると、確認したい項目がセットされた状態で、以下のような画面が起動します。
今回は、Core ML のテンプレートを用いてパフォーマンスを確認してみました。 推測したとおり、しっかりNeural Engineが使われているようです。他にも Core ML のメトリクスでは、モデルの名前が確認できます。
XCTest metrics を使ってアプリのパフォーマンスを継続的に確認する
最後に、XCTest metrics を用いて、特定メソッドのパフォーマンスを確認します。 XCTest metrics は、単体テストの一部として実装します。 普通の単体テストの一メソッド内で、XCTestCase クラスの measure メソッドを実装します。このメソッドは引数にクロージャを取り、クロージャに定義された処理に対する実行時間を測定します。クロージャに入った処理を複数回実行することで、メトリクスの baseline を算出します。今回は以下のようなコードでパフォーマンスを測定しました。
func testMetrics() throws { let metrics: [XCTMetric] = [XCTClockMetric(), XCTMemoryMetric(), XCTCPUMetric(), XCTStorageMetric()] self.measure(metrics: metrics) { let _ = ViewController.generate(prompt: “a photo of an astronaut riding a horse on mars”) } }
実行結果は以下のように表示されます。 一度 baseline を設定してからほぼ何も修正せずに再度テストしてみたのですが、14% 数値が悪化してしまいました。一回の実行時間が 200s を超えているので、10% としても 20s。テスト環境の関係上、完全に条件が揃えられているわけではありませんが、パフォーマンスが安定していないように感じました。筆者の主観ですが、ml-stable-diffusion は、ファーストパーティである Apple が GitHub にサードパーティ製ライブラリとして配布していることを考慮すると、プロダクションに投入するには時期尚早と判断したのかなと考えています。
おわりに
本記事では、iOS アプリのパフォーマンスを計測するツールをご紹介しました。計測することは、パフォーマンスを向上させる第一歩となります。
今日紹介したツールを使って効率的にボトルネックとなっている箇所を見つけ、アプリのパフォーマンスを向上させるきっかけとなれば幸いです。
公式サイトにはさらに詳しい情報がまとめられていますので、より深く知りたい方はこちらをご確認いただくとよいと思います。