はじめに
前回に引き続きAndroid Performance Patternの内容をまとめました。AndroidのPerformance効率化についてのTipsが書かれているのですが、いかんせん英語でとっつきにくいので(内容は少しだけどためになるものばかり)簡単にまとめました。
SparseArray
SparseArrayは、以下のようなヒエラルキーになっていてオブジェクトクラスの直下にある。Arrayというだけあり、配列のように利用できる。
大きな特徴はCollection, Map系とは違いオートボクシングを行わない。オートボクシングを行わないので、早い。
まずAuto Boxing(オートボクシング)とは
目的とメリット: primitive -> Object型への変換でprimitiveでは利用できなかった使い方・メソッドを利用できる。
オートボクシングとはJava5自体の機能である。
元来、リスト、コレクション(List, Collection)に対して、プリミティブ(int, flaot, booleanなど)な値は直接代入することができなかった。リスト、コレクションに代入するには、 プリミティブラッパークラスに代入 する必要性があった。(List, Collectioはオブジェクトしか扱えない。)
この プリミティブラッパークラスに代入 を自動で行ってくれる機能がオートボクシングである。
// 例)
// 元来の書き方:
List<Integer> list = new ArrayList<Integer>; //リストの初期化
list.add(Integer.valueOf(3)); //int -> Integerオブジェクトに変換してリストに追加
// オートボクシングによる書き方(Java5以降)
List<Integer> list = new ArrayList<Integer>; //リストの初期化
list.add(3); //int -> 上記作業を自動で行ってくれる。
オートボクシングでのループ
上記のようにオートボクシングにより便利になった側面は否めないが、逆に意識しなくてよくなったことにより、メモリ上でデメリットが生じる可能性がある。
- 以下において、上部のループはint型のみ。下部のループはInteger型をオートボクシングしてのループ。
- オートボクシングすると新しいオブジェクトを生成する必要があり、メモリ効率が少し悪くなる。(下記は動画からの転載だが、なぜ100ではなく83であるのかは謎です。)
Primitiveのデータサイズ
primitiveのデータサイズは以下だがオートボクシングすると16byteほどメモリ空間を新たに確保する。
オートボクシングしないクラス
上述したようにCollection, Map系にはオートボクシングがJava5の機能で含まれている。Androidでは、HashMapがオートボクシングを行うために、メモリパフォーマンスが悪くなってしまう可能性がある。そのために、GoogleはSparseMapを提供している。下記はprimitive型での要素インデックスを指定できるMapのリストである。
追記
- Allocation Tracker
Allocationの状態を可視化するために利用されるツール。これにより、どこでオートボクシングが行われているか開発者がわかる。
(動画で利用方法があったわけではないが言及していたので、触れました。こちらもまた後日機会があれば使い方をあげたいと思います。)