微信自用高性能通用键值组件MMKV已开源!
时间:2020-10-20
腾讯微信团队在2018年9月底宣布了开源MMKV,这是一个基于mmap内存映射的关键价值组件。底层的序列化/反序列化由protobuf实现,注重高性能和稳定性。最近,它也被移植到了安卓平台上,并且对外界是开源的。
简介
MMKV是一个基于mmap内存映射的键值组件,底层的序列化/反序列化由protobuf实现,具有高性能和强稳定性。从2015年年中开始,它已经在iOS微信上使用了近3年,其性能和稳定性已经过时间验证。最近,它也被移植到了安卓平台,并且是开源的。
最新源代码托管地址:https://github.com/Tencent/MMKV
MMKV从源头开始
在微信客户的日常操作中,特殊字符会不时出现(请参考文章《微信团队共享:微信iOS版如何防止特殊字符导致的群体爆炸和应用崩溃?》“微信团队共享:iOS版微信高性能通用键值组件的技术实践”,本文设计的技术方案是在键码前后加减计数器,通过检查计数器的异常来发现引起闪回的异常词。在小区数量较多的地方,如通话列表和通话界面,希望新增加的定时器不会影响滑动性能;此外,这些计数器应该永久存储,因为闪回可以随时发生。
因此,需要高性能的通用键值存储组件。我们调查了常见的组件,如共享参考、NSUserDefaults和SQLite,发现它们都不能满足如此严格的性能要求。考虑到该防崩溃方案的主要需求是实时写入,而mmap内存映射文件正好满足这一需求,我们尝试通过它实现一组键值组件。
MMKV原理
记忆准备
mmap内存映射文件提供了一个可以随时写入的内存块。应用程序只向其中写入数据,操作系统负责将内存写回文件,因此无需担心崩溃导致的数据丢失。
数据结构
在数据序列化方面,我们选择了protobuf协议,pb在性能和空间占用方面都有很好的表现。
写优化
考虑到主要的使用场景是频繁的写更新,我们需要增量更新的能力。我们考虑序列化增量kv对象,并将其附加到内存的末尾。
空间增长
使用追加实现增量更新带来了一个新问题,即如果您继续追加,文件大小将无法控制地增长。我们需要在性能和空间之间做出妥协。
有关更详细的设计原则,请参考MMKV原则。
监督办指南
安装导入
建议使用椰子肉:
安装光盘;;
打开命令行,cd到您的项目目录,并输入pod repo更新,使CocoaPods知道最新的MMKV版本;
打开Podfile并将Pod“MMKV”添加到您的应用程序目标中;
在命令行中输入podinstall
打开;xcworkspace文件由带Xcode的CocoaPods自动生成;
添加头文件#import,您可以愉快地开始您的MMKV之旅。
有关更多安装说明,请参见iOS设置。
快速开始
MMKV的使用非常简单,无需任何配置,并且所有更改都会立即生效,无需调用同步:
毫米千伏*毫米千伏=[毫米千伏默认值毫米千伏];
[mmkv SetBool:YES ForKey:@ " bool "];
BOOL Bvalue =[mmkv GetBOOLfWorkey:@ " BOOL "];
[mmkv setint 32:-1024 ForKey:@ " int 32 "];
int 32 _ t iValue =[mmkv getint 32 forkey:@ " int 32 "];
[mmkv setObject:@"hello,mmkv " ForKey:@ " string "];
nsString * str =[mmkv GetObjectOfClass:NSString . class分叉:@ " string "];
有关更详细的教程,请参见iOS教程。
性能比较
随机写入int 1w次,我们有以下性能比较:
有关更详细的性能比较,请参见iOS基准测试。
安卓指南
安装导入
建议使用Maven:
依赖关系{
实现' com.tencent:mmkv:1.0.10 '
//用任何可用版本替换“1.0.10”
}
更多安装说明,请参见安卓系统。
快速开始
MMKV的使用非常简单,所有的更改都会立即生效,无需调用同步或应用。应用程序启动时初始化MMKV,并设置MMKV的根目录(文件/mmkv/),例如,在维护活动中:
受保护的无效创建(捆绑保存状态){
super.onCreate(保存状态);
字符串rootDir = MMKV.initialize(此);
System.out.println("mmkv根:"+rootDir);
//……
}
MMKV提供了一个可直接使用的全球示例:
import com . Tencent . mmkv . MMKV;
//……
MMKV kv = MMKV . DefaultMMKV();
kv . encode(“bool”,真);
布尔Bvalue = kv . DeCodebool(" bool ");
千伏编码(“整数”。最小值);
int iValue = kv . DeCodeInt(“int”);
编码(“字符串”、“你好,来自mmkv”);
字符串字符串= kv.decodeString(“字符串”);
MMKV支持多进程访问。请参考安卓教程了解更多详细用法。
性能比较
写随机整数1千次,我们有以下性能比较: