Optimising Android app performance with ArrayMap

Android has transformed the way we use to think about the mobile OS. With increasing awareness about the programming languages. There is increase in new ideas as well as individuals eager to learn Android app development.

With Java as the Basic language for Android app development. Today I am going to write about:

How to optimize app performance by using Android’s ArrayMap over Java’s HashMap.

Whenever we need to store key, value pair, the first data structure that comes in your mind is Map in Android. And we will start using it at all places without any further thinking on its side effects.

With the usage of HashMap, Android Studio gives the warning that uses ArrayMap instead but most of us Neglect it.

Android offers the more powerful data structure than HashMap which we should consider using it.

Let us consider the scenario when we should consider using Android data structures and Why?

ArrayMap V/S HashMap

ArrayMap is a generic key->value mapping data structure that is designed to be more memory efficient than a traditional Java HashMap. It keeps its mappings in an array data structure — an integer array of hash codes for each item, and an Object array of the key/value pairs. This allows it to avoid having to create an extra object for every entry put into the map, and it also tries to control the growth of the size of these arrays more aggressively (since growing them only requires copying the entries in the array, not rebuilding a hash map).

P.S: That this implementation is not intended to be appropriate for data structures that may contain large numbers of items. It is generally slower than a traditional HashMap since lookups require a binary search and add and removes require inserting and deleting entries in the array. For containers holding up to hundreds of items, the performance difference is not significant, less than 50%.

How ArrayMap works

ArrayMap uses 2 arrays. The instance variables used internally are Object[ ] mArray to store the objects and the int[] mHashes to store hashCodes. When a key/value is inserted :

  • Key/Value is autoboxed.
  • The key object is inserted in the mArray where on the index in which it needs to pushed is searched using the binary search. (Thanks Or Gilad for correcting it).
  • A value object is also inserted in the position next to key’s position in mArray[ ].
  • The hashCode of the key is calculated and placed in mHashes[ ] at the next available position.

For searching a key :

  • Key’s hashCode is calculated
  • Binary search is done for this hashCode in the mHashes array. This implies time complexity increases to O(logN).
  • Once we get the index of hash, we know that key is at 2*index position in mArray and value is at 2*index+1 position.
  • Here the time complexity increases from O(1) to O(logN), but it is memory efficient. Whenever we play on a dataset of around 100,
  • there will no problem of time complexity, it will be non-noticeable. As we have the advantage of memory efficient application.

How HashMap works

HashMap is basically an Array of HashMap.Entry objects (Entry is an inner class of HashMap).

What happens when a key/value is inserted in HashMap ?

  • HashCode of the key is calculated, and that value is assigned to the hashCode variable of EntryClass.
  • Then, using hashCode we get the index of the bucket where it will be stored.
  • If the bucket is having a pre-existing element, the new element is inserted with the last element pointing to new one — essentially making the bucket a LinkedList.

Now, when you query it to get the value for a key, it comes in O(1).

But most important thing is that it comes at the cost of more space(memory).

In Android, memory matters a lot when it comes to the responsive applications, because of continuous allocation and deallocation of memory, the garbage collection occurs, so there will be a lag in your android application.

Garbage Collection is a tax on performance of an application.

When garbage collection is taking place, your application in not running. Ultimately, your application lags.

Recommended Data Structures:

ArrayMap<K,V> for HashMap<K,V>
ArraySet<K,V> for HashSet<K,V>
SparseArray<V> for HashMap<Integer,V>
SparseBooleanArray for HashMap<Integer,Boolean>
SparseIntArray for HashMap<Integer,Integer>
SparseLongArray for HashMap<Integer,Long>
LongSparseArray<V> for HashMap<Long,V>

If you like it then put a clap (👏 ) on it.

Mohammed Rampurawala

Written by

Android Engineer @GlobalLogic| #AndroidDev | #kotlin | #python | twitter | stackoverflow | github |machine learning https://mohom-portfolio.web.app/

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade