Androidのメモリ効率化Tips "SparseArray"


はじめに

前回に引き続き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の状態を可視化するために利用されるツール。これにより、どこでオートボクシングが行われているか開発者がわかる。
(動画で利用方法があったわけではないが言及していたので、触れました。こちらもまた後日機会があれば使い方をあげたいと思います。)