视频先行
下面是视频内容的脚本整理稿。如果你看了视频,那下面的文稿就不用看了。
正文
这是我在网上找到的一份 Android 键值对存储方案的性能测试对比(数越小越好):

可以看出,DataStore 的性能比 MMKV 差了一大截。MMKV 是腾讯在 2018 年推出的,而 DataStore 是 Android 官方在 2020 年推出的,并且它的正式版在 2021 年 8 月才发布。一个官方发布的、更(gèng)新的库,性能竟然比不过比它早两年发布的、第三方的库。而且我们能看到,更离谱的是,它甚至还比不过 SharedPreferences 。Android 官方当初之所以推出 DataStore,就是要替代掉 SharedPreferences,并且主要原因之一就是 SharedPreferences 有性能问题,可是测试结果却是它的性能不如 SharedPreferences。
所以,这到底是为什么?
啊,我知道了——因为 Google 是傻逼!
SharedPreferences:不知不觉被嫌弃
大家好,我是扔物线朱凯。
键值对的存储在移动开发里非常常见。比如深色模式的开关、软件语言、字体大小,这些用户偏好设置,很适合用键值对来存。而键值对的存储方案,最传统也最广为人知的就是 Android 自带的 SharedPreferences
。它里面的 -Preferences,就是偏好设置的意思,从名字也能看出它最初的定位。
SharedPreferences 使用起来很简单,也没什么问题,大家就这么用了很多年。——但!渐渐地,有人发现它有一个问题:卡顿,甚至有时候会出现 ANR。
MMKV:好快!
怎么办?换!2018 年 9 月,腾讯开源了一个叫做 MMKV 的项目。它和 SharedPreferences 一样,都是做键值对存储的,可是它的性能比 SharedPreferences 强很多。真的是强,很,多。在 MMKV 推出之后,很多团队就把键值对存储方案从 SharedPreferences 换到了 MMKV。
DataStore:官方造垃圾?
再然后,就是又过了两年,Google 自己也表示受不了 SharedPreferences 了,Android 团队公布了 Jetpack 的新库:DataStore,目标直指 SharedPreferences,声称它就是 Android 官方给出的 SharedPreferences 的替代品。
替代的理由,Android 团队列了好几条,但不出大家意料地,「性能」是其中之一:
也就是说,Android 团队直接抛弃了 SharedPreferences,换了个新东西来提供更优的性能。
但是,问题随之就出现了:大家一测试,发现这 DataStore 的性能并不强啊?跟 MMKV 比起来差远了啊?要知道,MMKV 的发布是比 DataStore 早两年的。DataStore 比人家晚两年发布,可是性能却比人家差一大截?甚至,从测试数据来看,它连要被它替代掉的 SharedPreferences 都比不过。这么弱?那它搞个毛啊!
Android 团队吭哧吭哧搞个新东西出来,竟然还没有市场上两年前就出现的东西强?这是为啥?
首先,肯定得排除「DataStore 是垃圾」这个可能性。虽然这猛一看、粗一想,明显就是 DataStore 垃圾、Google 傻逼,但是你仔细想想,这可能吗?
那如果不是的话,又是因为什么?——因为你被骗了。
MMKV 的一二三四
被谁骗了?不是被 MMKV 骗了,也不是具体的某个人。事情其实是这样的:
大家知道 MMKV 当初为什么会被创造出来吗?其实不是为了取代 SharedPreferences。
最早是因为微信的一个需求(来源:MMKV 组件现在开源了):
微信作为一个全民的聊天 App,对话内容中的特殊字符所导致的程序崩溃是一类很常见、也很需要快速解决的问题;而哪些字符会导致程序崩溃,是无法预知的,只能等用户手机上的微信崩溃之后,再利用类似时光倒流的回溯行为,看看上次软件崩溃的最后一瞬间,用户收到或者发出了什么消息,再用这些消息中的文字去尝试复现发生过的崩溃,最终试出有问题的字符,然后针对性解决。
那么这个「时光倒流」应该怎么做,就成了问题的关键。我们要知道,程序中的所有变量都是存活在内存里的,一旦程序崩溃,所有变量全都灰飞烟灭。
所以要想实现「时光倒流」,就需要把想回溯的时光预先记录下来。说人话就是,我们需要把界面里显示的文字写到手机磁盘里,才能在程序崩溃、重新启动之后,通过读取文件的方式来查看。
更麻烦的是,这种记录的目标是用来回溯查找「导致程序崩溃的那段文字」,而同时,正是因为没有人知道哪段文字会导致程序崩溃才去做的记录,这就要求每一段文字都需要先写入磁盘、然后再去显示,这样才能保证程序崩溃的时候那段导致崩溃的文字一定已经被记录到了磁盘。