Androidパフォーマンスの最適化-最適化セットクラスSparseArray&ArrayMapを使用


SparseArray
SparseArrayはHashMapよりもメモリを節約し、keyの自動箱詰め(intからIntegerタイプに移行)を回避するため、いくつかの条件下で性能が優れている.内部は2つの配列でデータ格納され、1つはkeyを格納し、もう1つはvalueを格納し、性能を最適化するために、内部ではデータを圧縮して疎配列のデータを表し、メモリ空間を節約します.keyとvalueはそれぞれ配列で表されています.
    private int[] mKeys;
    private Object[] mValues;

SparseArrayはkeyがintタイプのデータしか格納できません.また、SparseArrayはデータの格納と読み出しに二分ルックアップを使用しています.
 public void put(int key, E value) {
        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
        ...
        }
 public E get(int key, E valueIfKeyNotFound) {
        int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
        ...
        }

つまりputでデータを追加する場合、現在追加している要素のkeyの大きさを二分ルックアップ法と前のkeyで比較し、小さい順に並べますので、SparseArrayに格納されている要素はすべて要素のkey値が小さい順に並べられています.また、データを取得する際にも、二分ルックアップ法を用いて要素の位置を判断するので、データを取得する際には非常に速く、HashMapよりもずっと速く、HashMap取得データはEntry[]配列を巡って対応する要素を得るためである.
データの追加
public void put(int key, E value)

データの削除
 public void remove(int key)
public void delete(int key)

実はremove内部はdeleteを呼び出してデータを削除しています
データの取得
public E get(int key)

or
public E get(int key, E valueIfKeyNotFound)

このメソッドはkeyが存在しない場合にデフォルトで返されるvalueを設定します.
特有の方法
また、SparseArrayでは、データのクエリーを容易にする2つの独自の方法が用意されています.対応するkeyを取得します.
public int keyAt(int index)

対応するvalueを取得するには:
public E valueAt(int index)

SparseArray適用シーン
SparseArrayは性能が良いとはいえ、データの追加、検索、削除は一度に二分検索する必要があるため、データ量が大きい場合は性能が明らかではなく、少なくとも50%低下する.
次の2つの条件を満たすには、HashMapの代わりにSparseArrayを使用します.
  • データ量は大きくなく、千級以内のkeyはintタイプであることが望ましい.この場合のHashMapは、
  • の代わりにSparseArrayを使用することができる.
    HashMap<Integer, Object> map = new HashMap<>();

    次の代わりにSparseArrayを使用します.
    SparseArray<Object> array = new SparseArray<>();

    ArrayMap
    ArrayMapはマッピングのデータ構造で、メモリの最適化を考慮して設計されています.内部には2つの配列を使用してデータを格納し、1つの配列にはkeyのhash値を記録し、もう1つの配列にはValue値を記録します.SparseArrayと同様に、keyには二分法を使用して小さいものから大きいものまでソートされ、追加、削除、データを検索する場合は、まず二分検索法を用いて対応するindexを取得し、その後indexによって追加、検索、削除などの操作を行うため、適用シーンはSparseArrayと同様にデータ量が比較的大きい場合、その性能は50%未満に劣化する.
    データの追加
    public V put(K key, V value)

    データの取得
    public V get(Object key)

    データの削除
    public V remove(Object key)

    特有の方法
    SparseArrayと同様に、より便利なデータ取得方法も2つあります.
    public K keyAt(int index)
    public V valueAt(int index)

    ArrayMapアプリケーションシーン
    データ量は大きくなく、千級以内が望ましい.データ構造タイプはMapタイプである.
    ArrayMap<Key, Value> arrayMap = new ArrayMap<>();

    【注】:aip 19の次のバージョンと互換性を持つ場合は、インポートするパッケージはv 4パッケージが必要です.
    import android.support.v4.util.ArrayMap;
    まとめ
    SparseArrayもArrayMapもあまり差がありませんが、どれを使いますか?データ量がすべて千級以内であると仮定する場合:
    1.keyのタイプがintタイプと決定されている場合、自動的に箱詰めするプロセスを回避するため、SparseArrayを使用します.keyがlongタイプである場合、keyがlongタイプであることを保証するためにLongSparseArrayを提供します.
    2.keyタイプが他のタイプの場合、ArrayMapを使用する
    参考資料http://blog.csdn.net/u010687392/article/details/47809295
    https://juejin.im/entry/57c3e8c48ac24700634bd3cf
    http://www.cnblogs.com/zhaoxiaowei/p/3667689.html
    http://www.cnblogs.com/huanyou/p/5985303.html