Garminウォッチフェイスの作成:パフォーマンス

WatchUi::WatchFace::onUpdate()の呼び出しは、低電力モードで1分回に1回、高電力モードで1秒間に1回となっている。
ただ、高電力モードでもonUpdate()の処理に時間がかかってしまえば、複数秒で1回の更新タイミングになってしまう。

実際に、更新処理にどれぐらいの時間がかかってしまうのか、そのままでは計測することができないが、次の方法で解決できる。

計測方法

SDKの2.3からWatchUi::WatchFace::onPartialUpdate()が用意された。
このメソッドは、常に1秒1回の更新が行えるような仕組みとして用意されたもので、メソッド内の処理時間がある一定以下である限り、1秒1回の呼び出しがされるというもの。
そのため、この処理のために時間計測ができる仕組みが用意された。

計測結果の表示

計測結果は、デバイスシミュレーターで表示される。

File-View Watchface Diagnosticsを選択すると、onPartialUpdate()にかかった時間が表示される。
ここに表示されている時間はμ秒らしい。(デバイスシミュレーターに関してはマニュアル類が見つからないので、推測するしかないのが厳しい)
μ秒とした理由は、onPartialUpdate()に関連して用意されているWatchUi::WatchFaceDelegate::onPowerBudgetExceeded()で呼び出されたWatchFacePowerInfoの計測結果がミリ秒だということから。

上記メソッドが上の情報が表示されたプログラムでonPowerBudgetExceeded()が呼び出された結果が以下の通り。

平均実行時間が85.8ミリ秒となっており、デバイスシミュレーターに表示されていたトータル時間が86324だということからμ秒だと判断した。

計測を行うには

まず、以下のコードをWatchFaceを継承したクラスに入れる。

    function onPartialUpdate( dc ) {
    	onUpdate(dc);
    }

SDK 1.x台しか利用できないデバイスでは、上記コードは無視されるが、今回はonUpdate()にかかる時間を計測するためだけに、SDK 2.3以上の機能を利用する。

次に、ウォッチフェイスの実行機種をSDK 2.3以上のウォッチにする。
今回利用したのはVivoactive 4。

これで、シミュレーターを実行し、Watchface Diagnosticsを表示することで確認ができる。

Watchface Diagnosticsの内容

実際のコードをいじって、変化した情報より、次のように判断している。

  • Execution Code
    コードの実行時間。実装を変更したりすると内容が変わるため。
  • Graphics Time
    dc経由でグラフィックを描画する時間。描画内容の増加減で変わるため。
  • Display Time
    ちょっと不明。
  • Total Time
    Execution Code + Graphics Time + Display Timeの合計。

注意事項

対応したいデバイスがSDK 2.3以上でonPartialUpdate()を本来の意味で利用する場合は、onUpdate()の時間計測をするにはちょっと面倒かもしれない。

onPartialUpdate()を行う実処理を別に用意しておいて、onPartialUpdate()ないから計測したい処理を呼び出すようにしたらいいかもしれない。
以下のような感じで。

    function onPartialUpdateReal(dc) {
    	// 実際のonPartialUpdateの処理をここに書く
    }
    
    function onPartialUpdate( dc ) {
    	// 計測したい処理を実行する
    	onUpdate(dc);
    	// onPartialUpdateReal(dc);
    }

ちょっと簡単に計測した結果

実際のどれぐらいの高速化が行えるのかを調べてみた。

Garminウォッチフェイスの作成:デジタル時計の計測をしてみた結果は次のような感じになった。
実行:3.8ms、グラフィック:25ms

これに、秒を表示する処理を追加したら、次のようになった。
実行:3.9ms、グラフィック:28ms
実際の表示はこんな感じ。

3文字分の描画を追加しただけで、約3msほど処理時間が増えたことになる。

さらに、実装部分の無駄だと思われる処理を削除した結果は次の通り。
実行:3.6ms、グラフィック:28ms
実施した内容は、グラフィック描画時に行っていた座標計算をもうちょっと最適化し、文字列生成にLang.formatを使うのではなく、+を使って文字列を生成したこと。

この結果、実行処理部分に対して行う最適化は大きな影響を及ぼさないが、グラフィックへの描画内容の増加減に関しては、処理時間に顕著に影響を及ぼしてしまうことか。

コメント

タイトルとURLをコピーしました