中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

IOS緩存管理之YYCache使用詳解

發布時間:2020-09-02 19:38:29 來源:腳本之家 閱讀:224 作者:總李寫代碼 欄目:移動開發

前言:

最近一直在致力于為公司app添加緩存功能,為了尋找一個最佳方案,這幾天先做個技術預研,經過這兩天的查找資料基本上確定了兩個開源框架進行選擇,這兩個開源框架分別是:PINCache、YYCache,上篇已經簡單介紹了PINCache使用,本篇主要來學習一下YYCache的使用方式,以及和PINCache性能的簡單對比。

關于YYCache

1. 內存緩存(YYMemoryCache)

存儲的單元是_YYLinkedMapNode,除了key和value外,還存儲了它的前后Node的地址_prev,_next.整個實現基于_YYLinkedMap,它是一個雙向鏈表,除了存儲了字典_dic外,還存儲了頭結點和尾節點.它實現的功能很簡單,就是:有新數據了插入鏈表頭部,訪問過的數據結點移到頭部,內存緊張時把尾部的結點移除.就這樣實現了淘汰算法.因為內存訪問速度很快,鎖占用的時間少,所以用的速度最快的OSSpinLockLock

2. 硬盤緩存(YYDiskCache)

采用的是文件和數據庫相互配合的方式.有一個參數inlineThreshold,默認20KB,小于它存數據庫,大于它存文件.能獲得效率的提高.key:path,value:cache存儲在NSMapTable里.根據path獲得cache,進行一系列的set,get,remove操作更底層的是YYKVStorage,它能直接對sqlite和文件系統進行讀寫.每次內存超過限制時,select key, filename, size from manifest order by last_access_time desc limit ?1會根據時間排序來刪除最近不常用的數據.硬盤訪問的時間比較長,如果用OSSpinLockLock鎖會造成CPU消耗過大,所以用的dispatch_semaphore_wait來做.

YYCache使用

1.同步方式

  //模擬數據
  NSString *value=@"I want to know who is lcj ?";
  //模擬一個key
  //同步方式
  NSString *key=@"key";
  YYCache *yyCache=[YYCache cacheWithName:@"LCJCache"];
  //根據key寫入緩存value
  [yyCache setObject:value forKey:key];
  //判斷緩存是否存在
  BOOL isContains=[yyCache containsObjectForKey:key];
  NSLog(@"containsObject : %@", isContains?@"YES":@"NO");
  //根據key讀取數據
  id vuale=[yyCache objectForKey:key];
  NSLog(@"value : %@",vuale);
  //根據key移除緩存
  [yyCache removeObjectForKey:key];
  //移除所有緩存
  [yyCache removeAllObjects];

2.異步方式

  //模擬數據
  NSString *value=@"I want to know who is lcj ?";
  //模擬一個key
  //異步方式
  NSString *key=@"key";
  YYCache *yyCache=[YYCache cacheWithName:@"LCJCache"];
  //根據key寫入緩存value
  [yyCache setObject:value forKey:key withBlock:^{
    NSLog(@"setObject sucess");
  }];
  //判斷緩存是否存在
  [yyCache containsObjectForKey:key withBlock:^(NSString * _Nonnull key, BOOL contains) {
    NSLog(@"containsObject : %@", contains?@"YES":@"NO");
  }];

  //根據key讀取數據
  [yyCache objectForKey:key withBlock:^(NSString * _Nonnull key, id<NSCoding> _Nonnull object) {
    NSLog(@"objectForKey : %@",object);
  }];

  //根據key移除緩存
  [yyCache removeObjectForKey:key withBlock:^(NSString * _Nonnull key) {
    NSLog(@"removeObjectForKey %@",key);
  }];
  //移除所有緩存
  [yyCache removeAllObjectsWithBlock:^{
    NSLog(@"removeAllObjects sucess");
  }];

  //移除所有緩存帶進度
  [yyCache removeAllObjectsWithProgressBlock:^(int removedCount, int totalCount) {
    NSLog(@"removeAllObjects removedCount :%d totalCount : %d",removedCount,totalCount);
  } endBlock:^(BOOL error) {
    if(!error){
      NSLog(@"removeAllObjects sucess");
    }else{
      NSLog(@"removeAllObjects error");
    }
  }];

YYCache緩存LRU清理

LRU(Least Recently Used)算法大家都比較熟悉,翻譯過來就是“最近最少使用”,LRU緩存就是使用這種原理實現,簡單的說就是緩存一定量的數據,當超過設定的閾值時就把一些過期的數據刪除掉,比如我們緩存10000條數據,當數據小于10000時可以隨意添加,當超過10000時就需要把新的數據添加進來,同時要把過期數據刪除,以確保我們最大緩存10000條,那怎么確定刪除哪條過期數據呢,采用LRU算法實現的話就是將最老的數據刪掉。接下來我們測試一下

  YYCache *yyCache=[YYCache cacheWithName:@"LCJCache"];
  [yyCache.memoryCache setCountLimit:50];//內存最大緩存數據個數
  [yyCache.memoryCache setCostLimit:1*1024];//內存最大緩存開銷 目前這個毫無用處
  [yyCache.diskCache setCostLimit:10*1024];//磁盤最大緩存開銷
  [yyCache.diskCache setCountLimit:50];//磁盤最大緩存數據個數
  [yyCache.diskCache setAutoTrimInterval:60];//設置磁盤lru動態清理頻率 默認 60秒

模擬一下清理

  for(int i=0 ;i<100;i++){
    //模擬數據
    NSString *value=@"I want to know who is lcj ?";
    //模擬一個key
    NSString *key=[NSString stringWithFormat:@"key%d",i];
    [yyCache setObject:value forKey:key];
  }

  NSLog(@"yyCache.memoryCache.totalCost:%lu",(unsigned long)yyCache.memoryCache.totalCost);
  NSLog(@"yyCache.memoryCache.costLimit:%lu",(unsigned long)yyCache.memoryCache.costLimit);

  NSLog(@"yyCache.memoryCache.totalCount:%lu",(unsigned long)yyCache.memoryCache.totalCount);
  NSLog(@"yyCache.memoryCache.countLimit:%lu",(unsigned long)yyCache.memoryCache.countLimit);

  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(120 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

    NSLog(@"yyCache.diskCache.totalCost:%lu",(unsigned long)yyCache.diskCache.totalCost);
    NSLog(@"yyCache.diskCache.costLimit:%lu",(unsigned long)yyCache.diskCache.costLimit);

    NSLog(@"yyCache.diskCache.totalCount:%lu",(unsigned long)yyCache.diskCache.totalCount);
    NSLog(@"yyCache.diskCache.countLimit:%lu",(unsigned long)yyCache.diskCache.countLimit);

    for(int i=0 ;i<100;i++){
      //模擬一個key
      NSString *key=[NSString stringWithFormat:@"whoislcj%d",i];
      id vuale=[yyCache objectForKey:key];
      NSLog(@"key :%@ value : %@",key ,vuale);
    }

  });

YYCache和PINCache一樣并沒有實現基于最大內存開銷進行LRU,不過YYCache實現了最大緩存數據個數進行LRU清理,這一點也是選擇YYCache原因之一,對于YYCache磁盤LRU清理并不是及時清理,而是后臺開啟一個定時任務進行RLU清理操作,定時時間默認是60s。

YYCache與PINCache對比

 對于我這里的使用場景大部分用于緩存json字符串,我這里就以存儲字符串來對比一下寫入與讀取效率

1.寫入性能對比

YYCache

  //模擬數據
  NSString *value=@"I want to know who is lcj ?";
  //模擬一個key
  NSString *key=@"key";
  //YYCache
  YYCache *yyCache=[YYCache cacheWithName:@"LCJCache"];
  //寫入數據
  CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
  [yyCache setObject:value forKey:key withBlock:^{
    CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();

    NSLog(@" yyCache async setObject time cost: %0.5f", end - start);
  }];

  CFAbsoluteTime start1 = CFAbsoluteTimeGetCurrent();
  [yyCache setObject:value forKey:key];
  CFAbsoluteTime end1 = CFAbsoluteTimeGetCurrent();
  NSLog(@" yyCache sync setObject time cost: %0.5f", end1 - start1);

運行結果

IOS緩存管理之YYCache使用詳解

PINCache

   //PINCache
  //模擬數據
  NSString *value=@"I want to know who is lcj ?";
  //模擬一個key
  NSString *key=@"key";
  PINCache *pinCache=[PINCache sharedCache];
  //寫入數據
  CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
  [pinCache setObject:value forKey:key block:^(PINCache * _Nonnull cache, NSString * _Nonnull key, id _Nullable object) {
    CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();
    
    NSLog(@" pincache async setObject time cost: %0.5f", end - start);
  }];
  
  CFAbsoluteTime start1 = CFAbsoluteTimeGetCurrent();
  [pinCache setObject:value forKey:key];
  CFAbsoluteTime end1 = CFAbsoluteTimeGetCurrent();
  NSLog(@" pinCache sync setObject time cost: %0.5f", end1 - start1);

運行結果

IOS緩存管理之YYCache使用詳解

通過上面的測試可以看出 同樣大小的數據,無論同步方式還是異步方式,YYCache性能都要由于PINCache。

2.讀取性能對比

YYCache

  YYCache *yyCache=[YYCache cacheWithName:@"LCJCache"];
  //模擬一個key
  NSString *key=@"key";
  CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
  //讀取數據
  [yyCache objectForKey:key withBlock:^(NSString * _Nonnull key, id<NSCoding> _Nonnull object) {
    CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();
    NSLog(@" yyCache async objectForKey time cost: %0.5f", end - start);
  }];

  CFAbsoluteTime start1 = CFAbsoluteTimeGetCurrent();
  [yyCache objectForKey:key];
  CFAbsoluteTime end1 = CFAbsoluteTimeGetCurrent();
  NSLog(@" yyCache sync objectForKey time cost: %0.5f", end1 - start1);

運行結果:

IOS緩存管理之YYCache使用詳解

PINCache

 PINCache *pinCache=[PINCache sharedCache];
  //模擬一個key
  NSString *key=@"key";
  CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
  //讀取數據
  [pinCache objectForKey:key block:^(PINCache * _Nonnull cache, NSString * _Nonnull key, id _Nullable object) {
    CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();
    NSLog(@" pincache async objectForKey time cost: %0.5f", end - start);
  }] ;
  
  CFAbsoluteTime start1 = CFAbsoluteTimeGetCurrent();
  [pinCache objectForKey:key];
  CFAbsoluteTime end1 = CFAbsoluteTimeGetCurrent();
  NSLog(@" pinCache objectForKey time cost: %0.5f", end1 - start1);

運行結果:

IOS緩存管理之YYCache使用詳解

通過運行結果,在讀取方面YYCache也是優于PINCache。

總結:

經過一番查閱資料和自己寫例子測試,最終項目中決定使用YYCache進行緩存管理。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

澄城县| 越西县| 郁南县| 长汀县| 河南省| 赞皇县| 五华县| 尉氏县| 基隆市| 新干县| 德令哈市| 揭阳市| 瑞安市| 大新县| 定襄县| 阜平县| 太仆寺旗| 饶平县| 特克斯县| 泰兴市| 吴川市| 平顶山市| 开平市| 呼伦贝尔市| 舞阳县| 广元市| 扎囊县| 白沙| 阳朔县| 鄢陵县| 德兴市| 河曲县| 南投县| 荔浦县| 义乌市| 永善县| 鄄城县| 盐池县| 博罗县| 长春市| 祁阳县|