HashMap和SparseArray性能对比

当我们声明并实例化一个HashMap的时候,会出现如下提示:

HashMap初始化

系统建议我们用SparseArray来代替HashMap,都说SparseArray性能优于HashMap,那我们就来做个示例,用直观的数据来对比一下二者的性能。

public class MainActivity extends AppCompatActivity {
    private static final String TAG          = MainActivity.class.getSimpleName();
    private HashMap<Integer,byte[]> mMap     = new HashMap<>(16);
    private SparseArray<byte[]> mSparseArray = new SparseArray<>(16);
    private int mCount = 100*1000;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.btn_map_memory).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for (int i = 0;i < mCount;i++){
                            mMap.put(i,new byte[10]);
                        }
                        Log.i(TAG,"HashMap memory click...");
                    }
                }).start();
            }
        });
        findViewById(R.id.btn_sparsearray_memory).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for (int i = 0;i < mCount;i++){
                            mSparseArray.put(i,new byte[10]);
                        }
                        Log.i(TAG,"SparseArray memory click...");
                    }
                }).start();
            }
        });
        findViewById(R.id.btn_map_time).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        long start = System.currentTimeMillis();
                        for (int i = 0;i < mCount;i++){
                            mMap.get(i);
                        }
                        long current = System.currentTimeMillis();
                        Log.i(TAG,"HashMap time test:" + (current - start));
                    }
                }).start();
            }
        });
        findViewById(R.id.btn_sparsearray_time).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        long start = System.currentTimeMillis();
                        for (int i = 0;i < mCount;i++){
                            mSparseArray.get(i);
                        }
                        long current = System.currentTimeMillis();
                        Log.i(TAG,"SparseArray time test:" + (current - start));
                    }
                }).start();
            }
        });
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >

    <Button
        android:id="@+id/btn_map_memory"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_marginBottom="10dp"
        android:text="HashMap 测试内存"
        />
    <Button
        android:id="@+id/btn_sparsearray_memory"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_marginBottom="10dp"
        android:text="SparseArray 测试内存"
        />
    <Button
        android:id="@+id/btn_map_time"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_marginBottom="10dp"
        android:text="HashMap 测试时间"
        />
    <Button
        android:id="@+id/btn_sparsearray_time"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_marginBottom="10dp"
        android:text="SparseArray 测试时间"
        />

</LinearLayout>

简单新建一个Activity,写4个button,分别用来测试HashMap和SparseArray消耗内存大小,以及遍历HashMap和SparseArray的全部值所需要的时间。这里总数量设置为10万个,HashMap和SparseArray的值都为byte类型的数组,测试两者内存时分别用for循环向里面添加对应的值,测试两者时间的时候分别遍历两者全部的值。

AndroidStudio给我们提供了一个非常好用的性能监测的工具——Profiler,我们可以用这个工具来监测二者占用内存。

运行demo:

初始内存

可以看到,初始内存为5.5M,接下来,点击第一个按钮,测试HashMap里put10万个数据所占用内存:

map内存

可以看到,最终当内存稳定时,上升到13.2M,那么13.2-5.5 = 7.7M,说明HashMap占用7.7M内存。

紧接着点击第二个按钮,测试SparseArray里put10万个数据所占用内存:

总内存

可以看到,最终当内存稳定时,上升到17.3M,那么17.3 - 13.2 = 4.1M,说明SparseArray占用4.1M内存。一个7.7M,一个4.1M,将近一倍的差距。

好,从空间上,当数据量相同时,可以知道SparseArray比HashMap更节省内存,那么从时间上呢?

点击第三个和第四个按钮,看到Logcat输出如下日志:

时间对比

同样是遍历10万个值,HashMap用掉了1373毫秒,而SparseArray只用掉了72毫秒,20倍的差距,可见速度上也是大大优于HashMap。

通过这样一个小demo,我们直观的感受到了从空间和时间上,SparseArray的性能都要优于HashMap。之后的文章,我们会从源码的角度,进一步分析,为什么SparseArray的性能要优于HashMap。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值