【Java/Android效能優 4】PreloadDataCache支援預取的資料緩衝,使用簡單,支援多種緩衝演算法,支援不同網路類型,擴充性強

來源:互聯網
上載者:User

標籤:

 

本文轉自:http://www.trinea.cn/android/preloaddatacache/

本文主要介紹一個支援自動向前或向後擷取新資料的緩衝的使用及功能。Android圖片記憶體緩衝可見ImageCache。

 

主要特性:(1).使用簡單  (2).可自動預取新資料  (3).可選擇多種緩衝演算法(包括FIFO、LIFO、LRU、MRU、LFU、MFU等15種)或自訂緩衝演算法  (4).省流量效能佳(有且僅有一個線程擷取資料)  (5).支援不同類型網路處理  (6)緩衝可序列化到本地  緩衝可從檔案中恢複  (7).擴充性強  (8). 包含map的大多數介面

 

適用:Java和Android開發中擷取資料較耗時的應用,如網路通訊、響應慢資料擷取,在類似網易新聞、花瓣這類應用中可以起到很好的效果。對於圖片緩衝可直接使用ImageCache。

 

1、使用

引入[email protected](歡迎star和fork^_^)作為你項目的library(如何拉取代碼及添加公用庫),或是自己抽取其中的[email protected]部分使用。

測試情境:擷取每個資料需用時2秒,10次擷取的情境效果對比,緩衝前用時(ms):20004,緩衝後用時(ms):4026。快取命中率為80%。執行個體代碼如下:

 

private static String[]            data       = { "data1", "data2", "data3", "data4", "data5", "data6", "data7",        "data8", "data9", "data10", "data11", "data12", "data13", "data14", "data15", "data16", "data17", "data18",        "data19", "data20"                   };private static ArrayList<String>   keyList    = new ArrayList<String>();private static Map<String, String> dataSource = new HashMap<String, String>();private static int                 index      = 0; /*** 初始化資料來源*/static {    for (int i = 0; i < data.length; i++) {        String temp = Integer.toString(i);        dataSource.put(temp, data[i]);        keyList.add(temp);    }} /*** 類比從資料來源中擷取資料** @return*/public static String getSlowResponseData() {    try {        Thread.sleep(2000);    } catch (InterruptedException e) {        e.printStackTrace();    }    return dataSource.get(Integer.toString((index++) % keyList.size()));} public static void main(String[] args) {    // init cache, setOnGetDataListener    PreloadDataCache<String, String> cache = new PreloadDataCache<String, String>(5);    cache.setOnGetDataListener((new OnGetDataListener<String, String>() {         private static final long serialVersionUID = 1L;         @Override        public CacheObject<String> onGetData(String key) {            CacheObject<String> o = new CacheObject<String>();            o.setData(getSlowResponseData());            return o;        }    }));    cache.setCacheFullRemoveType(new RemoveTypeEnterTimeFirst<String>());     // get data by cache    int count = 10;    long start = System.currentTimeMillis();    for (int i = 0; i < count; i++) {        System.out.print(cache.get(Integer.toString(i), keyList).getData() + " ");    }    System.out.println("\r\n緩衝後用時(ms):" + (System.currentTimeMillis() - start) + "。快取命中率為" + cache.getHitRate()                       + "(" + cache.getHitCount() + "/" + (cache.getHitCount() + cache.getMissCount()) + ")");     // get data normal    start = System.currentTimeMillis();    for (int i = 0; i < count; i++) {        System.out.print(getSlowResponseData() + " ");    }    System.out.println("\r\n緩衝前用時(ms):" + (System.currentTimeMillis() - start));}

 

從上面的代碼中緩衝定義部分可以看出,只需要定義PreloadDataCache,並設定擷取資料的介面setOnGetDataListener,以後使用get擷取資料即可。

 

2、功能介紹
(1) 初始化緩衝
可以使用以下四種方式之一初始化緩衝
PreloadDataCache()
PreloadDataCache(int)
PreloadDataCache(int, int)
loadCache(String) 從檔案中恢複緩衝
支援緩衝大小和擷取資料線程池大小的設定,預設緩衝大小為SimpleCache#DEFAULT_MAX_SIZE,預設線程池大小根據系統Cpu個數設定。

 

(2)、設定資料擷取方式
public void setOnGetDataListener(OnGetDataListener<K, V> onGetDataListener)
設定資料擷取的方式。緩衝通過該介面擷取資料及預取資料。

 

(3) 擷取及預取資料
public CacheObject<V> get(K key, List<K> keyList) get某個key(同步),並且會根據key在keyList中的順序自動向前或向後擷取新資料進行緩衝
public CacheObject<V> get(K key) get某個key(同步),但不會自動擷取新資料進行緩衝
public void setForwardCacheNumber(int forwardCacheNumber) 向前預取資料個數設定,預設為PreloadDataCache#DEFAULT_FORWARD_CACHE_NUMBER

public void setBackwardCacheNumber(int backwardCacheNumber)向後預取資料個數設定預設,預設為PreloadDataCache#DEFAULT_BACKWARD_CACHE_NUMBER

 

(4)、設定緩衝演算法
public void setCacheFullRemoveType(CacheFullRemoveType<V> cacheFullRemoveType)
設定緩衝演算法,緩衝演算法即為緩衝滿時為了插入新資料,刪除舊資料的規則。

 

目前包括FIFO、LIFO、LRU、MRU、LFU、MFU、優先順序低先刪除、優先順序高先刪除、資料小先刪除、資料大先刪除、圖片小先刪除、圖片大先刪除、檔案小的先刪除、檔案大的先刪除、永不刪除。還可以通過實現CacheFullRemoveType來自訂緩衝演算法。。預設為RemoveTypeEnterTimeFirst,即先進先出。下面為詳細介紹

RemoveTypeEnterTimeFirst FIFO先進先出,先進入先刪除
RemoveTypeEnterTimeLast LIFO後進先出,後進入先刪除
RemoveTypeLastUsedTimeFirst LRU(Least Recently User),最先使用先刪除
RemoveTypeLastUsedTimeLast MRU(Most Recently Used),最近使用先刪除
RemoveTypeUsedCountSmall LFU(Least Frequently Used),使用頻率低先刪除
RemoveTypeUsedCountBig MRU(Most Frequently Used),使用頻率高先刪除
RemoveTypePriorityLow 優先順序低先刪除
RemoveTypePriorityHigh 優先順序低先刪除
RemoveTypeDrawableSmall 圖片小的先刪除
RemoveTypeDrawableLarge 圖片大的先刪除

RemoveTypeFileSmall 檔案小的先刪除

RemoveTypeFileLarge 檔案大的先刪除
RemoveTypeDataBig 資料大先刪除,根據快取資料的compareTo函數決定
RemoveTypeDataSmall 資料小先刪除,根據快取資料的compareTo函數決定
RemoveTypeNotRemove 不刪除,緩衝滿時不再允許插入新資料

 

自訂緩衝演算法只需要實現CacheFullRemoveType的compare方法即可。比較結果小於0表示會被先刪除

public class RemoveTypePriorityHigh<T> implements CacheFullRemoveType<T> {     private static final long serialVersionUID = 1L;     @Override    public int compare(CacheObject<T> obj1, CacheObject<T> obj2) {        return (obj2.getPriority() > obj1.getPriority()) ? 1 : ((obj2.getPriority() == obj1.getPriority()) ? 0 : -1);    }}

 

(5)、最佳化資料讀取
a. 設定資料讀取http逾時
public void setHttpReadTimeOut(int httpReadTimeOut)
若httpReadTimeOut小於0表示不設定逾時,預設不設定,單位為毫秒

b. 設定無網路不讀取
public void setContext(Context context)
設定context,網路連接失敗不會建立線程請求資料。

c. 支援不同網路類型的處理
public void setAllowedNetworkTypes(int allowedNetworkTypes)
設定允許的網路類型,可選擇PreloadDataCache#NETWORK_MOBILE、PreloadDataCache#NETWORK_WIFI或兩者都允許。預設兩者都允許。
注意:這個介面生效必須先setContext(Context context)

 

(6)、緩衝元素有效時間
public void setValidTime(long validTime)
設定緩衝元素有效時間,小於0表示不會失效,此時僅根據CacheFullRemoveType在緩衝滿時替換元素
通過protected boolean isExpired(K key)判斷某key是否到期

 

(7)、快取命中率
getHitRate()、getHitCount()、getMissCount()分別表示快取命中率、叫用次數、未叫用次數

 

(8) 序列化
序列化需要快取資料類型支援Serializable,關於序列化可參考Java Serializable的理解和總結

使用loadCache(String)從檔案中恢複緩衝
saveCache(String, SimpleCache)儲存緩衝到檔案

 

(9)、其他與map類似介面
public boolean containsKey(K key) 緩衝中是否包含該key
public CacheObject<V> remove(K key) 從緩衝中刪除某個key
public void clear() 清空緩衝
public Set<K> keySet() 緩衝中key集合
public Set<Map.Entry<K, CacheObject<V>>> entrySet() 緩衝中key,value索引值對集合
public Collection<CacheObject<V>> values() 緩衝中元素集合
public CacheObject<V> put(K key, V value) 手動插入某個元素
public CacheObject<V> put(K key, CacheObject<V> value) 手動插入某個元素
public CacheObject<V> get(K key) 得到某個key
public int getSize() 得到緩衝中有效元素個數
public int getMaxSize() 得到緩衝中元素最大個數

 

(10)得到設定
上面的set幾乎都可以通過對應的get得到相應value
使用getOnGetDataListener()得到擷取資料的方法
getForwardCacheNumber()得到自動向前緩衝的個數
getBackCacheNumber()得到自動向後緩衝的個數
getMaxSize()得到緩衝最大容量
getValidTime()得到有效時間,以毫秒計
getCacheFullRemoveType()得到cache滿時刪除元素類型

【Java/Android效能優 4】PreloadDataCache支援預取的資料緩衝,使用簡單,支援多種緩衝演算法,支援不同網路類型,擴充性強

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.