YYCache初学
来源:互联网 发布:java 创建服务 编辑:程序博客网 时间:2024/06/04 19:53
一。三种缓存方式的优缺点
TMMemoryCache 是TMCache 的内存缓存实现,最初由 Tumblr 开发,但现在已经不再维护了。TMMemoryCache 实现有很多 NSCache 并没有提供的功能,比如数量限制、总容量限制、存活时间限制、内存警告或应用退到后台时清空缓存等。TMMemoryCache 在设计时,主要目标是线程安全,它把所有读写操作都放到了同一个 concurrent queue 中,然后用 dispatch_barrier_async 来保证任务能顺序执行。它错误的用了大量异步 block 回调来实现存取功能,以至于产生了很大的性能和死锁问题。
PINMemoryCache 是 Tumblr 宣布不在维护 TMCache 后,由 Pinterest 维护和改进的一个内存缓存。它的功能和接口基本和 TMMemoryCache 一样,但修复了性能和死锁的问题。它同样也用 dispatch_semaphore 来保证线程安全,但去掉了dispatch_barrier_async,避免了线程切换带来的巨大开销,也避免了可能的死锁。
YYMemoryCache 是一个内存缓存,相对于 PINMemoryCache 来说,去掉了异步访问的接口,尽量优化了同步访问的性能,用 OSSpinLock 来保证线程安全。另外,缓存内部用双向链表和 NSDictionary 实现了 LRU 淘汰算法,相对于上面几个算是一点进步吧。
二。不同磁盘缓存的实现方式(基于文件读写、基于 mmap 文件内存映射、基于数据库)
TMDiskCache, PINDiskCache, SDWebImage 等缓存,都是基于文件系统的,即一个 Value 对应一个文件,通过文件读写来缓存数据。他们的实现都比较简单,性能也都相近,缺点也是同样的:不方便扩展、没有元数据、难以实现较好的淘汰算法、数据统计缓慢。
FastImageCache 采用的是 mmap 将文件映射到内存。用过 MongoDB 的人应该很熟悉 mmap 的缺陷:热数据的文件不要超过物理内存大小,不然 mmap 会导致内存交换严重降低性能;另外内存中的数据是定时 flush 到文件的,如果数据还未同步时程序挂掉,就会导致数据错误。抛开这些缺陷来说,mmap 性能非常高。
NSURLCache、FBDiskCache 都是基于 SQLite 数据库的。基于数据库的缓存可以很好的支持元数据、扩展方便、数据统计速度快,也很容易实现 LRU 或其他淘汰算法,唯一不确定的就是数据库读写的性能,为此我评测了一下 SQLite 在真机上的表现。iPhone6 64G 下,SQLite 写入性能比直接写文件要高,但读取性能取决于数据大小:当单条数据小于20K 时,数据越小 SQLite 读取性能越高;单条数据大于 20K 时,直接写为文件速度会更快一些。这和 SQLite 官网的描述基本一致。另外,直接从官网下载最新的 SQLite 源码编译,会比 iOS 系统自带的 sqlite3.dylib 性能要高很多。基于 SQLite 的这种表现,磁盘缓存最好是把 SQLite 和文件存储结合起来:key-value 元数据保存在 SQLite 中,而 value 数据则根据大小不同选择 SQLite 或文件存储。NSURLCache 选定的数据大小的阈值是 16K;FBDiskCache 则把所有 value 数据都保存成了文件。
YYDiskCache 也是采用的 SQLite 配合文件的存储方式,在 iPhone 6 64G 上的性能基准测试结果见下图。在存取小数据 (NSNumber) 时,YYDiskCache 的性能远远高出基于文件存储的库;而较大数据的存取性能则比较接近了。但得益于 SQLite 存储的元数据,YYDiskCache 实现了 LRU 淘汰算法、更快的数据统计,更多的容量控制选项。
关于锁:
OSSpinLock 自旋锁,性能最高的锁。原理很简单,就是一直 dowhile 忙等。它的缺点是当等待时会消耗大量 CPU 资源,所以它不适用于较长时间的任务。对于内存缓存的存取来说,它非常合适。
dispatch_semaphore 是信号量,但当信号总量设为 1 时也可以当作锁来。在没有等待情况出现时,它的性能比 pthread_mutex 还要高,但一旦有等待情况出现时,性能就会下降许多。相对于 OSSpinLock 来说,它的优势在于等待时不会消耗 CPU 资源。对磁盘缓存来说,它比较合适。
YYCache的组成
YYCache由YYCache、YYDiskCache、YYMemoryCache和YYKVStorage组成,其中YYKVStorage可直接对sqlite和文件系统进行读写(YYDiskCache的底层实现);
YYCache的使用
注意点
1.如果保存的自定义对象不遵守NSCoding
的协议或不实现NSCoding
协议的方法,就不能使用YYDiskCache进行长期缓存;
- (void)encodeWithCoder:(NSCoder *)aCoder;- (instancetype)initWithCoder:(NSCoder *)aDecoder;
- YYCache初学
- YYCache学习
- 源码解析--YYCache
- YYCache源码分析(二)
- YYCache源码分析(三)
- YYCache的基本使用
- YYCache 设计思路
- iOS—缓存YYCache框架
- YYCache源码分析(一)
- YYKit系列之——YYCache使用
- YYKit系列之——YYCache使用
- IOS缓存管理之YYCache使用
- IOS缓存管理之YYCache使用
- iOS源码解析—YYCache(概述)
- iOS源码解析—YYCache(YYMemoryCache)
- iOS源码解析—YYCache(YYDiskCache)
- iOS开发 数据存储之YYCache
- 如何使用YYCache存储自定义对象
- 使用AndroidStudio 导出Jar包
- [luogu2307]迷宫(并查集)
- jQuery ajaxError参数 详细整理
- Linux学习——Shell基础
- 用JGroups实现一个分布式任务分发系统
- YYCache初学
- Eclipse和java jdk 环境搭建及第一个java程序
- Android 软键盘事件imeOptions响应
- Java集合框架
- seo教程:网站SEO优化的七大基本要点!
- 设置input 的 checkbox样式
- java.text.ParseException: Unparseable date:
- SAPUI5教程——Content Densities
- NOIP 2015 提高组 day2 解题报告