Android開発でのパフォーマンスTips(1)
googleは公式ドキュメントとしてAndroid開発におけるパフォーマンス設計のベストプラクティスを公開しています。
Designing for Performance | Android Developers
どんなに優れたUIであってもパフォーマンスの悪いアプリはユーザにとって使いにくいものになってしまいます。
アプリのパフォーマンスチューニングは重要です。
今回は公式ドキュメントをベースにパフォーマンス設計のベストプラクティスのご紹介です。
Javaの世界で当たり前だったものが、Androidの世界では通用しないものも多々あるので覚えておきたいです。
基本的な考え方
Androidで良好なパフォーマンスを得るための基本的な考え方は
- 無駄な処理はしない
- 無駄なメモリは使わない
ことです。以降に出てくる原則はすべてこれにのっとったものです。
オブジェクト生成は避ける
オブジェクトを生成するとメモリ割り当てが行われるので、最終的にGCが走り、処理落ちしますよ、ということですね。
できる限りオブジェクト生成しない方法で実装するのが望ましいです。
- 文字列抽出を行う場合は、文字列コピーをせず、substringで取り出す
- 文字列加工はStringBufferを使い、一時的なStringオブジェクト生成を避ける
- Integerは使わずintを使う。可能な限りプリミティブで
などなど。
ネイティブメソッドを使う
文字列操作をする時、String.indexOf()やString.lastIndexOf()などのC/C++でネイティブ実装されているメソッドを使うことで、10~100倍パフォーマンスに違いが出ることがあるので、できる限りネイティブ実装のメソッドを使うこと。
インターフェースは使わない
オブジェクト指向になぞらえば、上記のようなケースでは多様性の恩恵を受けるために、Mapインターフェースを使った実装が好まれるが、Androidの実装ではパフォーマンス的にNG。インターフェースを使う場合、使わない時と比べて2倍近く遅くなることがあります。
ただし、外部へAPIを公開する場合は、パフォーマンスを犠牲にしてでもインターフェースを使うべきケースも出てくるので利用シーンに応じて最適な選択をすべき。
スタティックメソッドを使う
オブジェクトのフィールドにメソッド内でアクセスする必要がない場合、メソッドはスタティックにすべき。
仮想メソッドテーブルを捜査するコストがなくなるので高速になります。
クラス内部でgetter/setterは使わない
これまでJavaに慣れ親しんだ人は、フィールドにアクセスする場合、直接操作せず、getter/setterを使う習慣が身についていると思うが、パフォーマンスの観点から見ると、getter/setterを呼ぶよりもフィールドに直接アクセスした方が高速なので、クラス内部でフィールドを参照する場合は、直接フィールドへアクセスすべき。
ローカル変数でキャッシュする
直接フィールド参照するよりも、ローカル変数を参照する方が高速なので、何度も参照する必要があるフィールドの場合、ローカル変数にキャッシュすべき。
この場合、mCountフィールドとmltems[i]をループ回数分参照してしまうので、
あらかじめ上記のようにローカル変数にキャッシュすると、無駄なフィールド捜査走査が走らずにすみます。
メソッドの引数もローカル変数と同様の特性があります。
次回へ続きます。



s/捜査/走査/
ご指摘ありがとうございます。
修正しておきました。