您好!欢迎来到爱源码

爱源码

热门搜索: 抖音快手短视频下载   

HashMap、ArrayMap和SparseArray的源代码分析和性能比较 {免费源码}

  • 时间:2022-06-29 00:39 编辑: 来源: 阅读:290
  • 扫一扫,手机访问
摘要:HashMap、ArrayMap和SparseArray的源代码分析和性能比较 {免费源码}
Map和SparseArray是android系统API,是专门为移动设施定制的。 它肯定是用来代替HashMap来节省内存的。 一、源代码分析(由于篇幅所限,源代码分析部分将放在另一篇文章中)二。实现原理和数据结构的比较。性能测试IV的比较。总结一.源代码分析会在后面的下一篇文章中补充(都写在一篇文章里,太长了)二。实现原理和数据结构的比较1。hashMapPaste_Image.png hash从hashMap的结构可以看出,首先是键值 地图。实体具有以下数据结构:静态类hashmap条目 从时间效率上来说,使用hash算法,插入、搜索等操作非常快,而且一般情况下,每个数组值后面不会有很长的链表(因为hash冲突毕竟占比较小),所以如果不考虑空间利用,HashMap的效率是非常高的。 2.ArrayMapaste _ image.pngarraymap使用两个数组,mHashes用于存储每个键的哈希值,mArrray是mHashes的两倍大,键和值依次存储。 源代码的细节将在下一篇文章中解释。 现在我们抛开细节,只看重点句子:mHashes[index]= hash;mArray[index & lt;& lt1]= key;mArray[(index & lt;& lt1)+1] =值;相信大家看到这里后都明白原理了。 但是它如何查询呢?答案是二分搜索法。 插入时根据key的hashcode()方法获取哈希值,并计算mArrays中的索引位置。然后,相应的位置被二分搜索法找到并插入。当有散列冲突时,它将被插入索引的相邻位置。 综上所述,从空间的角度来说,ArrayMap存储一条信息的时候,需要存储一个hash值,一个key值,一个value值。 根据HashMap的粗略看,只减少了一个指向下一个实体的指针。 即使节省了一部分可视空间,内存节省也不是特别显著。 不是这样的吗?稍后将被验证 在时间效率方面,由于插入和搜索时使用的二分法,在没有哈希的情况下,搜索应该会更快。插入时,如果按顺序插入,效率会高,但如果随机插入,肯定会涉及大量的数组移动,数据量大,肯定不行。再考虑一下。如果不发生,每次插入的哈希值都比上一次小,就要一次又一次的移动,效率会压倒一切。 3.sparsearraypast _ image . pngsbarsearray相对简单很多,但不要认为它能取代前两者。只有当键为int时,才能使用sparseArray。注意是int而不是Integer,这也是提高sparseArray效率的一个点。取消装箱操作! 因为键是int,所以不需要任何哈希值。只要int值相等,就是同一个对象,简单粗暴。 插入和搜索也是基于二分法,所以原理基本和Arraymap一样,这里就不多说了。 总结一下:在空间上相比HashMap,去掉了哈希值的存储空间,没有下一个指针占用,还有少量的其他内存占用,看起来节省了不少。 时间对比:插入和搜索的情况和Arraymap基本相同,可能会有大量的数组移动。 但是它避免了打包的过程,所以不要小看打包的过程,还是很费时间的。 所以从源头来看,谁的效率高,取决于数据量。 好了,说半天分析。来点实际的,用数据说话!3.性能测试对比我们从插入和查询两个方面来对比一下。 1.插入性能时间比较测试代码:long start = system . current time millis();地图& lt整数,字符串& gthash = new HashMap & lt整数,字符串& gt();for(int I = 0;我& ltMAXi++) { hash.put(i,I+" ");} long ts = system . current time millis()-start;就贴这一段。另外两段代码无非就是替换HashMap,通过改变Max值来比较。 Paste_Image.png分析:从结果来看,数据量小的时候,差别不大(当然,如果数据量小,时间基准小,内容太多,差别也不大)。当数据量大于5000时,SparseArray最快,HashMap最慢。乍一看,似乎SparseArray是最快的,但需要注意的是。 也就是说,SparseArray和Arraymap是理想的情况。 尝试反向插入longstart = system。current time millis();HashMap & lt整数,字符串& gthash = new HashMap & lt整数,字符串& gt();for(int I = 0;我& ltMAXi++) { hash.put(MAX-1-i,I+" ");} long ts = system . current time millis()-start;Paste_Image.png分析:从结果来看,果然HashMap远远超过Arraymap和SparseArray,和前面的分析一致。 当然,当数据量很小时,比如小于1000,这个时间差可以忽略。 再来看一下空间对比:先说测试方法。因为内存是经过测试的,所以特别需要注意的是,GC不应该出现在测试过程中。如果发生GC,数据将会不准确。想了想,我用了一个比较简单的方法:runtime.getruntime()。total memory()//获取总内存runtime.getruntime()。应用程序申请的freememory()。 Paste_Image.png值得注意的是,当MAX值较大时,代码执行过程中可能会发生gc。这时可以用Android Monitor的内存窗口同时监控内存,没有GC的进程结果会有效。 假设数据量比较大,每次测试完都要进行手动GC,这样测试基本每次都能成功;因为数据量不是特别大,测试过程中只有少数情况会GC,所以没有进一步探索其他方式,比如设置虚拟机参数延长GC时间。有时间可以做。 从上面的数据:Paste_Image.png可以看出,在内存占用方面,SparseArray确实比HashMap和ArrayMap好很多。通过数据观察,大致节省30%左右。但是前面提到的ArrayMap的体现,优化效果有限,和HashMap差不多。 2.用long start = system . current time millis()比较搜索性能;SparseArray & lt字符串& gthash = new SparseArray & lt字符串& gt();for(int I = 0;我& ltMAXi++){ hash . get(I);} long ts = system . current time millis()-start;Paste_Image.png发现SparseArray比HashMap快,与之前的假设不符。二分搜索法比哈希快吗?再想想,因为用这样的代码测试有点不公平,而且因为SparseArray没有装箱,HashMap有装箱过程,看起来不公平。 那就想办法再测试一遍,ArrayList < IntEntity & gtintEntityList = new ArrayList & ltIntEntity & gt();private void boxing(){ for(int I = 0;我& ltMAXi++){ IntEntity entity = new IntEntity();entity . i1 = I;entity . I2 = integer . value of(I);intEntityList.add(实体);} } class IntEntity { int i1整数I2;}当你给HashMap和ArrayMap的时候,提前打包似乎比较公平。 long start = system . current time millis();HashMap & lt整数,字符串& gthash = new HashMap & lt整数,字符串& gt();for(int I = 0;我& ltMAXi++){//hash . get(I);hash . get(intentitylist . get(I). I2);} long ts = system . current time millis()-start;Paste_Image.png有不同的结果。HashMap是最快的查询,这只是逻辑上的。但是我们正常使用的时候,不管是打包还是不打包,结合使用SparseArray是最高效的。 说了这么多,终于到总结的时候了。 四。总结1。当数据量较小时,一般认为小于1000。当你的key是int的时候,使用SparseArray确实是一个非常好的选择,内存可以节省30%左右。与使用HashMap相比,它的键值不需要装箱,所以时间性能平均比HashMap好。建议使用!2.与SparseArray相比,ArrayMap的特点是键值类型不受限制,在任何情况下都可以替代HashMap。但通过研究和测试发现,ArrayMap的内存节省并不显著,大约在10%左右,但时间性能最差。当然1000以内的数据量无所谓,加上只有在API >: =19才可以使用。个人建议没必要!最好用HashMap。 预计这也是google在创建新的HashMap时没有提醒我们使用的原因。 目前我在公司负责与热修复相关的工作,主要以稳健热修复为主。 欢迎有兴趣的同学加入群交流。 image.png


  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【技术支持|常见问题】1502企业站群-多域名跳转-多模板切换(2024-04-09 12:19)
【技术支持|常见问题】1126完美滑屏版视频只能显示10个(2024-03-29 13:37)
【技术支持|常见问题】响应式自适应代码(2024-03-24 14:23)
【技术支持|常见问题】1126完美滑屏版百度未授权使用地图api怎么办(2024-03-15 07:21)
【技术支持|常见问题】如何集成阿里通信短信接口(2024-02-19 21:48)
【技术支持|常见问题】算命网微信支付宝产品名称年份在哪修改?风水姻缘合婚配对_公司起名占卜八字算命算财运查吉凶源码(2024-01-07 12:27)
【域名/主机/服务器|】帝国CMS安装(2023-08-20 11:31)
【技术支持|常见问题】通过HTTPs测试Mozilla DNS {免费源码}(2022-11-04 10:37)
【技术支持|常见问题】别告诉我你没看过邰方这两则有思想的创意广告! (2022-11-04 10:37)
【技术支持|常见问题】你正确使用https了吗? [php源码](2022-11-04 10:37)

联系我们
Q Q:375457086
Q Q:526665408
电话:0755-84666665
微信:15999668636
联系客服
企业客服1 企业客服2 联系客服
86-755-84666665
手机版
手机版
扫一扫进手机版
返回顶部