亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統(tǒng) > Android > 正文

Android中SparseArray性能優(yōu)化的使用方法

2019-12-12 06:41:57
字體:
供稿:網(wǎng)友

之前一篇文章研究完橫向二級菜單,發(fā)現(xiàn)其中使用了SparseArray去替換HashMap的使用.于是乎自己查了一些相關(guān)資料,自己同時對性能進(jìn)行了一些測試。首先先說一下SparseArray的原理.

  SparseArray(稀疏數(shù)組).他是Android內(nèi)部特有的api,標(biāo)準(zhǔn)的jdk是沒有這個類的.在Android內(nèi)部用來替代HashMap<Integer,E>這種形式,使用SparseArray更加節(jié)省內(nèi)存空間的使用,SparseArray也是以key和value對數(shù)據(jù)進(jìn)行保存的.使用的時候只需要指定value的類型即可.并且key不需要封裝成對象類型.

  樓主根據(jù)親測,SparseArray存儲數(shù)據(jù)占用的內(nèi)存空間確實(shí)比HashMap要小一些.一會放出測試的數(shù)據(jù)在進(jìn)行分析。我們首先看一下二者的結(jié)構(gòu)特性.

  HashMap是數(shù)組和鏈表的結(jié)合體,被稱為鏈表散列.

  SparseArray是單純數(shù)組的結(jié)合.被稱為稀疏數(shù)組,對數(shù)據(jù)保存的時候,不會有額外的開銷.結(jié)構(gòu)如下:

  這就是二者的結(jié)構(gòu),我們需要看一下二者到底有什么差異...

  首先是插入:

  HashMap的正序插入:

 HashMap<Integer, String>map = new HashMap<Integer, String>(); long start_map = System.currentTimeMillis(); for(int i=0;i<MAX;i++){   map.put(i, String.valueOf(i)); } long map_memory = Runtime.getRuntime().totalMemory(); long end_map = System.currentTimeMillis()-start_map; System.out.println("<---Map的插入時間--->"+end_map+"<---Map占用的內(nèi)存--->"+map_memory);

 執(zhí)行后的結(jié)果:

 <---Map的插入時間--->914 <---Map占用的內(nèi)存--->28598272

SparseArray的正序插入:

 SparseArray<String>sparse = new SparseArray<String>(); long start_sparse = System.currentTimeMillis(); for(int i=0;i<MAX;i++){    sparse.put(i, String.valueOf(i)); } long sparse_memory = Runtime.getRuntime().totalMemory(); long end_sparse = System.currentTimeMillis()-start_sparse; System.out.println("<---Sparse的插入時間--->"+end_sparse+"<---Sparse占用的內(nèi)存--->"+sparse_memory);//執(zhí)行后的結(jié)果:<---Sparse的插入時間--->611<---Sparse占用的內(nèi)存--->23281664

   我們可以看到100000條數(shù)據(jù)量正序插入時SparseArray的效率要比HashMap的效率要高.并且占用的內(nèi)存也比HashMap要小一些..這里的正序插入表示的是i的值是從小到大進(jìn)行的一個遞增..序列取決于i的值,而不是for循環(huán)內(nèi)部如何執(zhí)行...

  通過運(yùn)行后的結(jié)果我們可以發(fā)現(xiàn),SparseArray在正序插入的時候,效率要比HashMap要快得多,并且還節(jié)省了一部分內(nèi)存。網(wǎng)上有很多的說法關(guān)于二者的效率問題,很多人都會誤認(rèn)為SparseArray要比HashMap的插入和查找的效率要快,還有人則是認(rèn)為Hash查找當(dāng)然要比SparseArray中的二分查找要快得多.

  其實(shí)我認(rèn)為Android中在保存<Integer,Value>的時候推薦使用SparseArray的本質(zhì)目的不是由于效率的原因,而是內(nèi)存的原因.我們確實(shí)看到了插入的時候SparseArray要比HashMap要快.但是這僅僅是正序插入.我們來看看倒序插入的情況.

  HashMap倒序插入:

 System.out.println("<------------- 數(shù)據(jù)量100000 散列程度小 Map 倒序插入--------------->"); HashMap<Integer, String>map_2 = new HashMap<Integer, String>(); long start_map_2 = System.currentTimeMillis(); for(int i=MAX-1;i>=0;i--){   map_2.put(MAX-i-1, String.valueOf(MAX-i-1)); } long map_memory_2 = Runtime.getRuntime().totalMemory(); long end_map_2 = System.currentTimeMillis()-start_map_2; System.out.println("<---Map的插入時間--->"+end_map_2+"<---Map占用的內(nèi)存--->"+map_memory_2);  //執(zhí)行后的結(jié)果: <------------- 數(shù)據(jù)量100000 Map 倒序插入---------------> <---Map的插入時間--->836<---Map占用的內(nèi)存--->28598272

  SparseArray倒序插入:

System.out.println("<------------- 數(shù)據(jù)量100000 散列程度小 SparseArray 倒序插入--------------->");SparseArray<String>sparse_2 = new SparseArray<String>();long start_sparse_2 = System.currentTimeMillis();for(int i=MAX-1;i>=0;i--){  sparse_2.put(i, String.valueOf(MAX-i-1));}long sparse_memory_2 = Runtime.getRuntime().totalMemory();long end_sparse_2 = System.currentTimeMillis()-start_sparse_2;System.out.println("<---Sparse的插入時間--->"+end_sparse_2+"<---Sparse占用的內(nèi)存--->"+sparse_memory_2);//執(zhí)行后的結(jié)果<------------- 數(shù)據(jù)量100000 SparseArray 倒序插入---------------><---Sparse的插入時間--->20222<---Sparse占用的內(nèi)存--->23281664

 通過上面的運(yùn)行結(jié)果,我們?nèi)匀豢梢钥吹?SparseArray與HashMap無論是怎樣進(jìn)行插入,數(shù)據(jù)量相同時,前者都要比后者要省下一部分內(nèi)存,但是效率呢?我們可以看到,在倒序插入的時候,SparseArray的插入時間和HashMap的插入時間遠(yuǎn)遠(yuǎn)不是一個數(shù)量級.由于SparseArray每次在插入的時候都要使用二分查找判斷是否有相同的值被插入.因此這種倒序的情況是SparseArray效率最差的時候.

 SparseArray的插入源碼我們簡單的看一下..

 public void put(int key, E value) {    int i = ContainerHelpers.binarySearch(mKeys, mSize, key); //二分查找.    if (i >= 0) { //如果當(dāng)前這個i在數(shù)組中存在,那么表示插入了相同的key值,只需要將value的值進(jìn)行覆蓋..      mValues[i] = value;    } else { //如果數(shù)組內(nèi)部不存在的話,那么返回的數(shù)值必然是負(fù)數(shù).      i = ~i; //因此需要取i的相反數(shù).      //i值小于mSize表示在這之前. mKey和mValue數(shù)組已經(jīng)被申請了空間.只是鍵值被刪除了.那么當(dāng)再次保存新的值的時候.不需要額外的開辟新的內(nèi)存空間.直接對數(shù)組進(jìn)行賦值即可.      if (i < mSize && mValues[i] == DELETED) {        mKeys[i] = key;        mValues[i] = value;        return;      }      //當(dāng)需要的空間要超出,但是mKey中存在無用的數(shù)值,那么需要調(diào)用gc()函數(shù).      if (mGarbage && mSize >= mKeys.length) {        gc();                // Search again because indices may have changed.        i = ~ContainerHelpers.binarySearch(mKeys, mSize, key);      }      //如果需要的空間大于了原來申請的控件,那么需要為key和value數(shù)組開辟新的空間.      if (mSize >= mKeys.length) {        int n = ArrayUtils.idealIntArraySize(mSize + 1);        //定義了一個新的key和value數(shù)組.需要大于mSize        int[] nkeys = new int[n];        Object[] nvalues = new Object[n];        // Log.e("SparseArray", "grow " + mKeys.length + " to " + n);        //對數(shù)組進(jìn)行賦值也就是copy操作.將原來的mKey數(shù)組和mValue數(shù)組的值賦給新開辟的空間的數(shù)組.目的是為了添加新的鍵值對.        System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);        System.arraycopy(mValues, 0, nvalues, 0, mValues.length);        //將數(shù)組賦值..這里只是將數(shù)組的大小進(jìn)行擴(kuò)大..放入鍵值對的操作不在這里完成.        mKeys = nkeys;        mValues = nvalues;      }      //如果i的值沒有超過mSize的值.只需要擴(kuò)大mKey的長度即可.      if (mSize - i != 0) {        // Log.e("SparseArray", "move " + (mSize - i));        System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);        System.arraycopy(mValues, i, mValues, i + 1, mSize - i);      }      //這里是用來完成放入操作的過程.      mKeys[i] = key;      mValues[i] = value;      mSize++;    }  } 

  這就是SparseArray插入函數(shù)的源碼.每次的插入方式都需要調(diào)用二分查找.因此這樣在倒序插入的時候會導(dǎo)致情況非常的糟糕,效率上絕對輸給了HashMap學(xué)過數(shù)據(jù)結(jié)構(gòu)的大家都知道.Map在插入的時候會對沖突因子做出相應(yīng)的決策.有非常好的處理沖突的方式.不需要遍歷每一個值.因此無論是倒序還是正序插入的效率取決于處理沖突的方式,因此插入時犧牲的時間基本是相同的.

  通過插入.我們還是可以看出二者的差異的.

  我們再來看一下查找首先是HashMap的查找.

 System.out.println("<------------- 數(shù)據(jù)量100000 Map查找--------------->"); HashMap<Integer, String>map = new HashMap<Integer, String>();     for(int i=0;i<MAX;i++){    map.put(i, String.valueOf(i)); } long start_time =System.currentTimeMillis(); for(int i=0;i<MAX;i+=100){      map.get(i); } long end_time =System.currentTimeMillis()-start_time; System.out.println(end_time);  //執(zhí)行后的結(jié)果 <!---------查找的時間:175------------>

 SparseArray的查找:

 System.out.println("<------------- 數(shù)據(jù)量100000 SparseArray 查找--------------->"); SparseArray<String>sparse = new SparseArray<String>(); for(int i=0;i<10000;i++){    sparse.put(i, String.valueOf(i)); } long start_time =System.currentTimeMillis();     for(int i=0;i<MAX;i+=10){    sparse.get(i); } long end_time =System.currentTimeMillis()-start_time; System.out.println(end_time); //執(zhí)行后的結(jié)果 <!-----------查找的時間:239---------------->

  我這里也簡單的對查找的效率進(jìn)行了測試.對一個數(shù)據(jù)或者是幾個數(shù)據(jù)的查詢.二者的差異還是非常小的.當(dāng)數(shù)據(jù)量是100000條.查100000條的效率還是Map要快一點(diǎn).數(shù)據(jù)量為10000的時候.這就差異性就更小.但是Map的查找的效率確實(shí)還是贏了一籌.

  其實(shí)在我看來.在保存<Integer,E>時使用SparseArray去替換HashMap的主要原因還是因?yàn)閮?nèi)存的關(guān)系.我們可以看到.保存的數(shù)據(jù)量無論是大還是小,Map所占用的內(nèi)存始終是大于SparseArray的.數(shù)據(jù)量100000條時SparseArray要比HashMap要節(jié)約27%的內(nèi)存.也就是以犧牲效率的代價去節(jié)約內(nèi)存空間.我們知道Android對內(nèi)存的使用是極為苛刻的.堆區(qū)允許使用的最大內(nèi)存僅僅16M.很容易出現(xiàn)OOM現(xiàn)象的發(fā)生.因此在Android中內(nèi)存的使用是非常的重要的.因此官方才推薦去使用SparseArray<E>去替換HashMap<Integer,E>.官方也確實(shí)聲明這種差異性不會超過50%.所以犧牲了部分效率換來內(nèi)存其實(shí)在Android中也算是一種很好的選擇吧.

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
日韩欧美在线播放视频| 久草免费在线视频| 日本久久网站| 国产欧美日韩精品丝袜高跟鞋| 91麻豆一区二区| 欧美—级高清免费播放| 日韩欧美在线视频播放| 欧美一区二区视频在线观看| 五月香视频在线观看| 美女日批视频在线观看| 国产福利a级| aaa在线免费观看| 久久久99精品免费观看| 成人精品亚洲人成在线| 人禽交欧美网站免费| 亚洲精品视频播放| 国产亚洲精品女人久久久久久| 成人黄色片免费| 亚洲AV成人精品| 亚洲精品视频区| 久久亚洲国产精品尤物| 日韩精品无码一区二区| 999精品嫩草久久久久久99| 国产精品亚洲一区二区三区在线观看| 国产成人自拍视频在线| 未来日记在线观看| 国产精品啪啪啪视频| 国产成人av无码精品| 精品国产百合女同互慰| 国产99对白在线播放| 国产欧美一区二区三区在线观看视频| 台湾佬中文娱乐久久久| 久久人人爽人人爽人人片av高清| 韩国97影院| 国产精品视频一区麻豆| 国产一级特黄a大片99| 亚洲欧美中文字幕| 天堂www中文在线资源| 五月天激情四射| 性刺激的欧美三级视频| 亚洲激情欧美| 欧美三日本三级少妇三99| 欧美韩日一区二区三区四区| 不卡中文字幕| 日韩av三级在线观看| 中文字幕第五页| 国产精品麻豆99久久久久久| 九九热这里只有在线精品视| 日韩欧美成人网| 中文字幕日韩欧美精品高清在线| 国产欧美日韩伦理| 91在线码无精品| 国产区精品在线观看| 亚洲午夜精品久久久中文影院av| 深夜影院在线观看| 蜜桃av噜噜一区| 色呦呦网站一区| 激情综合网五月婷婷| 欧美日韩综合在线| 国产裸体歌舞团一区二区| 国产精品极品国产中出| 亚洲 欧美 日韩 综合| 看全色黄大色黄大片免责看的| 嫩草在线视频| 亚洲午夜精品在线观看| 天堂va蜜桃一区二区三区| 9l视频自拍九色9l视频成人| 夜夜添无码一区二区三区| 国产美女视频免费观看下载软件| 97久久久精品综合88久久| 国产白嫩美女无套久久| 欧美wwwsss9999| 蜜臀久久99精品久久一区二区| gogogo免费高清日本写真| 国产第一页在线视频| 成视频在线免费观看| 亚洲欧美日韩综合国产aⅴ| 影音先锋中文在线观看| 日韩精品一线二线三线| 黄色免费网址大全| 国产91精品一区二区麻豆亚洲| 99999精品视频| 欧美无砖砖区免费| av日韩一区| 欧美男男gaytwinkfreevideos| 亚州精品国产精品乱码不99按摩| 成人激情电影一区二区| 国产成人久久777777| 亚洲成人动漫精品| 国产精品7m凸凹视频分类| 久久av高潮av无码av喷吹| 日韩一区国产二区欧美三区| 亚洲高清毛片一区二区| 给个网站可以在线观看你懂的| 无码国产69精品久久久久同性| 精品国产导航| 国产免费av国片精品草莓男男| 精品少妇一区| 成人h动漫在线| 日韩av电影在线播放| 免费a视频在线观看| 久久久久久久国产精品视频| 亚洲一区在线直播| 国产欧美精品区一区二区三区| 国产精品99免视看9| 国产真实乱人偷精品| 欧美成人高清| 狠狠色丁香婷婷| 天美一区二区三区| 国内自拍视频一区| 久久精品国产久精国产爱| 97精品国产99久久久久久免费| 成年人网站在线| 国产亚洲欧美日韩在线一区| 三级在线观看| 午夜精品久久久久久久男人的天堂| 久久aⅴ国产欧美74aaa| 国产伦精品一区二区三区视频痴汉| 激情综合网五月激情| 欧美日本在线视频中文字字幕| 美女黄毛**国产精品啪啪| 亚洲一区二区在线视频观看| 日韩中文字幕一区二区三区| 国产在线视频不卡二| 日韩精品专区在线影院观看| 欧美在线视频网| 久久99精品久久久久久水蜜桃| 色欧美激情视频在线| 久久精品久久99| 国产清纯白嫩初高中在线观看性色| 色综合久久综合网欧美综合网| 伊人国产在线| 国产在线观看h| 国产成人精品在线| 欧美第一精品| 欧美一级免费在线| 四虎影院中文字幕| 日韩免费不卡av| 久久久久久亚洲综合| 欧美在线极品| 久久综合伊人77777麻豆最新章节| 久久亚洲国产视频| 日韩人体视频一二区| 亚洲高清不卡在线观看| 综合另类专区| 久久久久久久久久久久久av| 国产精品日韩在线播放| 日本三级电影网| 99欧美视频| 欧美一级欧美三级| 天堂在线一区二区三区| 男生操女生视频在线观看| 特黄aaaaaaaaa毛片免费视频| 国产精品一区二区三| 日韩最新在线视频| 曰皮视频在线播放免费的| 精品人妻一区二区乱码| 色婷婷av一区二区三区丝袜美腿| 日本天堂在线| 麻豆中文一区二区| 欧美人妖视频| www男人天堂| 激情五月六月婷婷| 色总=综合色| 日本久久电影网| 日韩欧美色综合网站| 欧美成人免费va影院高清| 人人网欧美视频| 天天干天天操天天干天天操| 国产91精品黑色丝袜高跟鞋| 深夜福利网站| 91九色porn在线资源| 久久久噜噜噜久噜久久综合| 亚洲欧洲精品天堂一级| 日韩欧国产精品一区综合无码| 国产日产欧美一区二区三区| 999一区二区三区| 久久av国产紧身裤| 国产原创视频在线| 久久精品超碰| 国产大学生自拍| 欧美性生交xxxxx| 成人黄色午夜影院| 国产1卡2卡三卡四卡网站| 香蕉精品视频在线| 欧洲av不卡| www.xx日本| 亚洲美女动态图120秒| 欧美激情国产日韩| 亚洲一区二区三区sesese| 嫩草懂你的影院| 操人视频91| 综合136福利视频在线| 欧美老少做受xxxx高潮| 欧美日韩美女在线观看| 欧美福利一区二区| 真实原创一区二区影院| 欧美第一页在线| 国产在线视频99| 久久露脸国语精品国产91| 成人看片毛片免费播放器| 精品视频在线一区二区| 午夜视频在线播放| 色噜噜夜夜夜综合网| 日本视频一区二区在线观看| 国产一区二区三区三区在线观看| 这里只有精品丝袜| 精品国产中文字幕| 成片免费观看| 青娱乐国产在线| 极品少妇一区二区三区| 伊人成综合网yiren22| 97超碰青青草| 亚洲男人的天堂网| 45www国产精品网站| 久久久蜜臀国产一区二区| 日韩毛片在线| 免费一区二区三区在线视频| 欧美 日韩 国产精品| 国产精品久久久久久久久电影网| 亚洲黄页网在线观看| 国产又黄又爽免费视频| 韩国三级hd中文字幕有哪些| 国内露脸中年夫妇交换精品| 国产精品视频一区在线观看| 亚洲图片欧洲图片日韩av| 亚洲欧美一区二区三区四区| 精品国产一区二区三区四区在线观看| 久久久国产精品无码| 亚洲国产欧美在线人成| 国产主播在线看| 日韩亚洲精品电影| 97婷婷大伊香蕉精品视频| 欧美在线二区| 丝袜美腿亚洲一区二区| 偷拍自拍亚洲| 最新国产在线视频| 最近中文字幕免费视频| 免费影视亚洲| 特级丰满少妇一级| 国产麻豆精品久久一二三| 一区二区久久久久久| 国产97在线亚洲| 成全视频全集| 欧美极品少妇xxxxⅹ高跟鞋| 国产精品中出一区二区三区| 国产va在线视频| 精品国产乱码久久久久久88av| 97精品国产综合久久久动漫日韩| av动漫免费看| 日本熟妇人妻中出| 久久久久久国产精品一区| 欧美成人国产va精品日本一级| 在线观看xxx| 欧美激情综合五月色丁香小说| 艳色歌舞团一区二区三区| 久久久久久少妇| 在线观看色视频| 亚洲不卡中文字幕无码| 777777av| 日韩福利片在线观看| 欧美做a欧美| 日产精品久久久一区二区福利| 日韩美女黄色片| 亚洲精品美腿丝袜| 一二三区高清| 国产精品jizz在线观看老狼| 国产黄视频在线观看| 国产高清不卡二三区| 久操视频在线免费观看| 中文字幕巨乱亚洲| 91精品精品| 国产高清一级毛片在线不卡| 国产一二三四在线| 欧美jizz18hd性欧美| 国产成人av一区二区| 99精品国产视频| 国产在线拍揄自揄视频不卡99| 免费欧美一级片| 日韩欧美国产视频| 在线播放91灌醉迷j高跟美女| 亚洲精品中文在线观看| 久久精品人人做人人综合| 欧美jizzhd精品欧美另类| 乱精品一区字幕二区| 四虎永久免费在线| 日韩精品――色哟哟| 国产精品无码电影在线观看| 欧美在线观看视频一区二区| 国产精品视频自拍| caoporen国产精品视频| 精品无人区一区二区三区竹菊| 欧美精品手机在线| 免费无码毛片一区二区app| 国产美女做爰免费视频软件| 国产综合在线播放| 无码人妻少妇色欲av一区二区| 牛人国产偷窥女洗浴在线观看| 亚洲国产精品成人久久综合一区| 久久人人爽人人爽人人片av免费| 亚洲电影成人av99爱色| 五月天亚洲精品| 毛片在线不卡| 美女91在线看| 鲁鲁在线中文| 久久久爽爽爽美女图片| 国产视频第一页| 精品sm捆绑视频| 国产91亚洲精品久久久| 69**夜色精品国产69乱| 一区二区三区免费在线| 日日噜噜夜夜狠狠久久丁香五月| 日本精品999| 国产91av在线| 天天操综合520| 影音先锋中文字幕第一页| 一区二区乱码| 久久av一区二区三区| 国产97在线播放| 久久经典视频| 91视频网入口| 国内精品免费在线观看| 亚洲精品国产免费| 久久亚洲成人精品| 日本污视频在线观看| 欧美一区二区三区小说| 国产精品最新自拍| 中文字幕在线视频区|