MMKV_Android数据持久化方案调研-MMKV SP REALM ROOM WCDB...
官方方案對比
SharedPreference
簡稱SP,使用鍵值對的形式保存原始類型的數據,默認以XML格式的文件來存儲這些數據
適用場景:存儲量小、簡單的數據
優缺點:有自己的內存級的緩存,在數據量小的時候讀取較快,但是跨進程不安全,數據量大的時候加載緩慢,全量寫入,容易引起ANR
SQLite
適用場景:比較復雜數據類型并且較大的數據量,成千上萬的級別
優缺點:相比SP來說,需要在數據量較大的時候才有優勢,數據的獲取較慢,大量寫入需要注意使用事務批處理,性能較高,如果頻繁的單次插入性能不高,直接通過sql操作比較繁瑣,可以考慮orm框架
File
適用場景:顧名思義比較適用于文件類型的存儲,如圖片或者存儲一些簡單的文本數據或二進制數據
優缺點:最基本的存儲方式,它不對存儲的內容進行任何的格式化處理,所有數據都是原封不動地保存到文件當中的
小結
由于我們目前使用的SP方案,我們的痛點,性能差,和ANR問題,考慮換一種數據存儲方案,首先我們的數據存儲的場景并不是復雜數據類型,量上也不是太大,所以優先考慮的就是MMKV,為了更清楚的了解MMKV的優缺點,所以對比參考下
開源方案對比
各種方案簡介
名稱
MMKV
Realm
WCDB
Room
方案
mmap
nosql
SQLCipher
SQLite
版本
1.0.24
6.0.2
1.0.8
2.2.3
size
0.15mb
1.5mb
0.7mb
0.05mb
遷移
從SP遷移方便
從SQLite遷移方便
場景
替換SP
替換SQLite
替換SQLite
替換SQLite
注:
size 為armeabi-v7a架構下打包增量大小
mmkv包含lib_c++shared庫的size為0.3mb
性能對比
初始化
初始化
MMKV
SP
Realm
Room
WCDB
耗時
30ms
4ms
60ms
15ms
80ms
內存
1mb
約1mb
約2mb
1mb
2mb
cpu峰值
16%
20%
18%
15%
15%
讀寫速度和數據文件大小等數據對比
SP
執行次數
寫入耗時
讀取耗時
數據文件
字符串
200
51ms
4ms
8kb
字符串
1000
171ms
6ms
42kb
Java實體
1000
220ms
87ms
172kb
MMKV
執行次數
寫入耗時
讀取耗時
數據文件
字符串
200
8ms
5ms
4kb
字符串
1000
20ms
9ms
16kb
Java實體
1000
117ms
93ms
128kb
Realm
執行次數
寫入耗時
讀取耗時
數據文件
字符串
200
229ms
74ms
32kb
字符串
1000
606ms
122ms
288kb
Java實體
1000
760ms
130ms
576kb
Room
執行次數
寫入耗時
讀取耗時
數據文件
字符串
200
636ms
160ms
32kb
字符串
1000
1350ms
475ms
48kb
Java實體
1000
1298ms
432ms
68kb
wcdb
執行次數
寫入耗時
讀取耗時
數據文件
字符串
200
636ms
160ms
32kb
字符串
1000
1350ms
475ms
48kb
Java實體
1000
1298ms
432ms
68kb
內存消耗
內存消耗
MMKV
SP
初始化 + 查詢1k條
1.7mb
1.2mb
初始化 + 查詢1w條
3.6mb
2.8mb
初始化 + 查詢5w條
10.7mb(文件8mb)
8.5mb(文件8.6mb)
指標備注
字符串數據:含有隨機數的10個字節
運行手機:華為 Mate10
執行線程:子線程
統計方式:取3次平均值
內存消耗:業務代碼讀取對應數據后釋放本地對象后的內存增量
由于序列化反序列化會有緩存,Java實體
SP寫入為apply異步方式
Realm、WCDB、Room 的插入操作均為單條插入
MMKV、SP 讀取和寫入Java實體對象數據時間包含實體類序列化和反序列化時間,不過由于序列化反序列化會有緩存,時間會稍偏小
測試整理
初始化性能,cpu峰值和內存增長都相差無幾,耗時來看,由于SP和Room都是系統原生的方案,耗時較短。
MMKV和SP新增了內存消耗一項,主要是因為自己有一份內存級別的緩存,需要驗證下對內存的影響,從測試數據來看,這兩個方案內存增長相當,可以接受。
MMKV使用protobuf存儲,SP使用xml。protobuf相比xml來說性能更好,體積也會減小,但是真實存儲空間來看,mmkv的擴容機制(在空間不足時會申請一倍的空間)可能會導致實際使用空間變大,相比較SP的占用的存儲空間就是真實的數據大小。
開源方案總結
MMKV
MMKV 通過 mmap 內存映射文件,提供一段可供隨時寫入的內存塊,App 只管往里面寫數據,由操作系統負責將內存回寫到文件,不必擔心 crash 導致數據丟失。而SP則
MMKV 是一個跨平臺的解決方案,寫入性能相比sp有很大提升,適用于需要一個通用的 key-value 存儲組件,有跨進程訪問需求,尤其是對現在sp存儲方案的不滿的同學,mmkv同時支持了sp的遷移支持,基本上不用調整太多的代碼,遷移事項下面會詳述。
Realm
Realm作為一款移動端的NoSQL框架,官方定位就是替代SQLite等關系型數據庫,跨平臺,性能優秀,有可視化的查看工具。不足也比較明顯,不論是集成包size還是數據文件都有點大。另外Realm要求當前Bean對象必須直接繼承RealmObject,侵入性非常強。有線程限制,不能跨線程使用數據對象。另外我在寫測試demo的時候發現了一個坑,如果一個線程查詢出列表后,另一個線程再去增加或刪除會使得本地數據文件產生備份,導致數據庫文件急速增長,達到幾百MB,并且不會自動清理,官方對這個也有說明:
WCDB
WCDB是一個高效、完整、易用的移動數據庫框架,基于SQLCipher,支持iOS, macOS和Android
Room
Room并不是一個數據庫,他是在 SQLiteo 的基礎上提供了一個抽象層,讓用戶能夠在充分利用 SQLite 的強大功能的同時,獲享更強健的數據庫訪問機制。并保留了靈活的接口適配層。目前WCDB已經支持接入Room:github.com/Tencent/wcd…
ObjectBox
想嘗試的同學可以試試
ObjectBox,這個也是GreenDao作者的另一力作,據說性能比Realm還要好,由于本次是對老項目中的SP存儲方案選型替換,暫時先不對比ObjectBox了,后續有時間了完善下相關對比記錄,有幾篇文章大家可以參考
notes.devlabs.bg/realm-objec…
chejdj.github.io/android/201…
綜述
總結下吧,sp 和 mmkv 都是自己有一份內存級別的緩存,所以查詢非常快,但是如果數據量過大,會造成內存溢出,mmkv官方也對這點有說明,不要超過100mb,其實對正常的數據來說,肯定到不了這個限制,如果30mb以上的數據,都要考慮使用數據庫類型的存儲了,上面測試數據對于數據庫類型的存儲不太公平,主要針對單次頻繁插入查詢的使用場景,數據庫使用場景一般會多條數據通過事務批量寫入,查詢的時候也會查詢一類數據集合。綜上所述,目前采用mmkv替換sp的實現還是有很大收益的,性能和跨進程上都有優勢,并且避免了sp的ANR問題,體積上也沒有加大多少;如果數據庫方案,建議采用Room,或者在嘗試下上面說的但是沒在本次測試對比的objectbox。感覺要注意的挺多,不過零零散散只整理了這么點...
MMKV遷移參考
遷移官方文檔:github.com/Tencent/MMK…
MMKV 不支持 Serializable,但是可以考慮把 Serializable 的 java對象 轉換成 byte 存入MMKV
MMKV初始存儲空間4kb,不足的時擴容最少是一倍,并且為了效率在移除key value不會減小磁盤存儲空間,官方提供了kv.trim方法去縮減磁盤存儲空間,不過官方建議調用時機是有大量移除操作的時候執行,一般無需考慮存儲文件增長問題,但這個時機不好掌握,不過感覺可以定期清理一次
SP#getAll SP#registerOnSharedPreferenceChangeListener 等方法不支持,調用會拋出運行時異常,需要注意。getAll因為擦除了類型,所以不支持,感覺這是mmkv相對較弱的地方,也為以后遷移其他存儲方案增加了成本
一些 Android 設備(API level 19)在安裝/更新 APK 時可能出錯, 導致 libmmkv.so 找不到。然后就會遇到 java.lang.UnsatisfiedLinkError 之類的 crash。有個開源庫 ReLinker 專門解決這個問題,不過現在還在支持19的應用應該不多了
對于歷史項目SP數據可能比較龐大,這樣直接使用官方提供的mmkv#importFromSharedPreferences方法直接對一個文件進行遷移,會造成耗時過長的問題,目前Demo測試數據:測試機型華為Mate10,一個4MB左右的SP的文件遷移到MMKV大約耗時80ms左右,到了線上應該還會更長,所以為了避免初次使用卡住的體驗問題,這里提供兩個解決思路:1.在使用前統一遷移,并且給予用戶一個遷移數據的提示;2.在初次使用的時候后臺靜默遷移。目前我們使用的是第二種思路,這種情況需要保證數據的準確性,如果有同學有興趣可以留言探討
參考
官方和網上各種對比測試文章
github.com/Tencent/MMK…
github.com/Tencent/wcd…
github.com/realm/realm…
dxinl.github.io/2018/03/29/…
andyken.github.io/2017/10/26/…
juejin.im/post/5a0e7b…
www.jianshu.com/p/f001acf3d…
juejin.im/entry/59b78…
juejin.im/entry/58e4c…
關于找一找教程網
本站文章僅代表作者觀點,不代表本站立場,所有文章非營利性免費分享。
本站提供了軟件編程、網站開發技術、服務器運維、人工智能等等IT技術文章,希望廣大程序員努力學習,讓我們用科技改變世界。
[Android數據持久化方案調研-MMKV SP REALM ROOM WCDB...]http://www.zyiz.net/tech/detail-139172.html
總結
以上是生活随笔為你收集整理的MMKV_Android数据持久化方案调研-MMKV SP REALM ROOM WCDB...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 找出一个数组中唯一一个出现2次的数字
- 下一篇: C++11 bind注意事项(传引用参数