Android開発でのパフォーマンスTips(2)

By daichi1128
このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

AndroidパフォーマンスTips、前回の続きです。
Android開発でのパフォーマンスTips(1) | Techfirm Android Lab

定数はファイナルで宣言する

上記のようにfinalなしで定数を定義した場合、intValを参照するときにフィールド走査が実行されるが、

このようにfinal宣言をするとintValは直接VMが参照できるようになるため、高速になる。

メソッドやクラスに関してはfinal宣言をつけてもコード保守の面では効果があるが、パフォーマンス面でのメリットはない。
また、ローカルメソッドについてもパフォーマンス面では効果はないので要注意。

foreachループは気をつける

上のようなjava1.5から加わったforeach構文を使う時、配列[]のループの場合は配列オブジェクト、長さをコンパイラがローカル変数にキャッシュするようなコードにしてくれるが、CollectionsのようなIterableなオブジェクトの場合、一時的なオブジェクトが暗黙的に生成されてしまうので、Iterableなオブジェクトのループの場合は、従来のfor文でローカル変数でキャッシュさせるのが吉。

enumは使わない

enumは便利だが、サイズとパフォーマンス面ではちょっとキツイ。

上記のようなenumを定義しただけで、900 byteのclassファイルが生成され、実行時にはそれぞれの列挙子に対して、クラスの初期化が実行されてしまう。これらはstatic finalなintに置き換えることが可能なので、できる限りenumは使うべきではないが、これも利便性とのトレードオフで、APIとして用意しておきたい場合は、enumを使った方がよいだろう。
ただ、その時はordinal()メソッドを使うと多少はパフォーマンス的によいかもしれない。
たとえば、

上のようなコードを

こんな形に直すとよい。
常にこちらが早くなるという保障はないけど基本的には高速なはず。

インナークラス利用時はパッケージスコープを

たとえば、こんなインナークラスを使ったコードがある。

この場合、インナークラスInnerのstuff()メソッドは正しく”Value is 27″を表示するが、Fooクラスのprivateなフィールド、メソッドへアクセスしているため、コンパイラは以下のようなメソッドを生成し、これらを使ってアクセスを試みる。

Innerクラス内ではFooクラスのフィールド、メソッドを直接参照している風だが、実際には上記のアクセサメソッドを介して参照されるため、パフォーマンスが下がる。

こうしたパフォーマンス劣化を防ぐために、Fooクラスのフィールド、メソッドをprivateではなく、パッケージスコープ(修飾子なし)に置き換えることだ。

ただし、これも利便性とはトレードオフなので設計時に要検討。

floatは使わない

Pentium CPUの浮動小数点プロセッサが登場してからはデスクトップマシン等では、純粋な整数同士の演算よりも浮動小数点を含んだ演算の方が高速になったが、こと組み込み系に関しては未だに浮動小数点演算をサポートしていないことが多々ある。そうした場合、浮動小数点演算はソフトウェア的に処理されるためパフォーマンス劣化につながる。
だもんで、floatはやめましょう。

パフォーマンスサンプル値

これは表なので公式ドキュメントに譲ります。
Designing for Performance | Android Developers

まとめ

パフォーマンスを改善するポイントは多々あるけど、規模や設計と照らし合わせて最適なチョイスをしましょうねということになりそうです。

関連する投稿