上篇主要講述了我們?cè)谄綍r(shí)iOS開發(fā)中常見的一些緩存及其區(qū)別慷暂,雖然這已經(jīng)滿足了絕大多數(shù)的場(chǎng)景槽袄,但是當(dāng)我們遇到特殊場(chǎng)景的時(shí)候,又該如何呢滓玖。
緩存策略
一般來說,客戶端使用LRU的緩存策略就已經(jīng)足夠站辉,但是在特定場(chǎng)合就不是那么適用了呢撞。比如淘寶每秒百萬級(jí)別的查詢,如果使用LRU饰剥,那么可能有些熱門商品就會(huì)被清理出緩存,從而得不償失了摧阅。
- First In First Out (FIFO)
- Last In First Out (LIFO)
- Least Recently Used (LRU)
- Time aware Least Recently Used (TLRU)
擁有過期時(shí)間的LRU汰蓉,常見的比如http緩存 - Most Recently Used (MRU)
- Random Replacement (RR)
- Segmented LRU (SLRU)
- Least-Frequently Used (LFU)
- Least Frequent Recently Used (LFRU)
- LFU with Dynamic Aging (LFUDA)
如果真的有如此特殊的場(chǎng)景,就需要我們?nèi)ミx擇最優(yōu)的策略來保證緩存的命中率了棒卷。
memory map
其中很多方案都提到了內(nèi)存映射的技術(shù)顾孽。
內(nèi)存映射會(huì)少去很多的解析編碼祝钢、內(nèi)存拷貝操作,所以性能上會(huì)優(yōu)于普通的文件讀寫若厚。
但是內(nèi)存映射本身就存在一些缺陷拦英,比如32/64操作系統(tǒng)的兼容性,大端小端的兼容性测秸,字節(jié)對(duì)齊問題疤估。所以并不是任何情況下都適合使用內(nèi)存映射。如果需要保證兼容性霎冯,則需要在設(shè)計(jì)的時(shí)候就要考慮到這樣的問題铃拇。
搜索優(yōu)化
作為數(shù)據(jù)存儲(chǔ)最頻繁的當(dāng)然是查詢功能,那么如何保證查詢的性能呢沈撞,那么就涉及到索引了慷荔。
操作系統(tǒng)本身的文件系統(tǒng)就帶有B/B+數(shù)所做的索引,所以我們?cè)谀夸浵虏檎乙粋€(gè)文件其實(shí)是很快的缠俺,就算這個(gè)文件夾下內(nèi)容非常的多显晶。所以一般情況下我們并不需要為文件系統(tǒng)做額外的索引優(yōu)化。
如果是內(nèi)存中的緩存壹士,那么使用hash表是最通用的一種方式了磷雇。如果是數(shù)組則要考慮好承載能力了,少量的數(shù)據(jù)可能沒有問題墓卦,當(dāng)數(shù)量到達(dá)一定程度后就會(huì)暴露出來倦春。這時(shí)候可以使用自平衡二叉樹、B樹落剪、跳躍鏈表等來做優(yōu)化了睁本。
sqlite是我們使用最多的一種數(shù)據(jù)存儲(chǔ)方式,提升sqlite搜索速度的方式就是對(duì)某列增加索引忠怖,具體需要根據(jù)具體情況來分析呢堰。默認(rèn)的sqlite索引是B樹,也可以配置為R樹索引凡泣,在坐標(biāo)數(shù)據(jù)庫(kù)表可能會(huì)表現(xiàn)更優(yōu)秀枉疼。
存儲(chǔ)格式
數(shù)據(jù)的存儲(chǔ)格式也是非常關(guān)鍵的一個(gè)部分。
像UserDefault這種全量更新的方式鞋拟,在單一數(shù)據(jù)變化的時(shí)候就需要全部重新序列化并且全部保存骂维,所以如果擁有大量數(shù)據(jù)或者數(shù)據(jù)非常龐大的時(shí)候,就會(huì)變得效率低下贺纲。
像ImageCache這種按照單文件保存航闺,如果是小數(shù)據(jù),每次都需要去讀磁盤,反而效率會(huì)降低潦刃。由于磁盤的讀取和寫入并不是單字節(jié)的侮措,都是按塊讀寫是最有效率的,所以多個(gè)小數(shù)據(jù)可以一次性讀取和寫入乖杠。
如果是像sqlite那樣按照chunk來局部更新文件分扎,則需要非常小心的處理每個(gè)數(shù)據(jù)存儲(chǔ)模塊,同時(shí)也要非常小心處理多線程的問題胧洒。另外也需要添加索引來確保效率畏吓。
如果是隨機(jī)讀為主的情況下,sqlite能夠完成這個(gè)任務(wù)略荡,但是如果是以寫為主庵佣,那么sqlite就可能出現(xiàn)性能問題(雖然按照移動(dòng)客戶端來說不太可能有這么大的寫的需求)。
最后
如何去選擇緩存和存儲(chǔ)方案汛兜,還是需要根據(jù)實(shí)際情況巴粪,通常一個(gè)通用的方案已經(jīng)足夠,但是在某些特殊場(chǎng)景還是需要我們?nèi)プ约涸O(shè)計(jì)這一套方案粥谬。