前言
项目中由于对于启动的优化,配置表量并不是特别大,但启动时长却不低,但对于应用类来说,对启动时长要求很严格。
我希望能做到毫秒级的加载体验,所以有了这个优化
旧方案
使用pb表配置,用工具转成pb格式,启动后加载到lua table
原始的pb文件在2M多,读取到内存中后,会增加20多M的内存开销
加载时长是高端机500ms多, 依赖机器性能,机器越差,加载越慢
另外,table还做了一个__newindex包装,是为了防止有代码误修改, 这个也增加了转换的时长
希望的优化目标是,这个启动加载能减少到100ms以下
新方案
使用一个自定义的二进制格式,也是用工具预先转换一下
【】文件头
【】列信息
【】数据表中全部字符串
【】不定长的数组
【】关键列查找表
【】行数据(定长结构,如果该列是字符串这类的不定长数据,则存储指针(偏移), 指向真正的数据
【0】 【1】 【2】 ... 【N】
【值或偏移】
通过重载 __index, 直接查找返回相应的变量,也正常的lua table访问基本一致
优化思路
1、采用内存文件格式,内存格式与文件格式完全一致,这个完全去除了数据解码的开销
这样配置文件大小与CPU的性能就不相关了,完全能满足毫秒级的加载体验
2、数据压缩,减少内存开销
自适应压缩整数,对于boo, 小于255的整数,使用1Byte存储
对于小于65535的整数,使用2Byte存储
对于 float, 如果事实上填的是整数,就自动转换成整数,按整型压缩
所有的字符串连续,通过偏移访问
扫描字符串,统计重码率,重码只存一个
找描字符串,拆分长字符串(比如路径),拆两成两个部分,公共路径只存一个,减少字符串的长度
3、查询速度优化
使用定长的二维格式,支持按行列随机访问,内存连续,Cpu Cache命中率高,能提供更高的查询性能。
经过这些优化后,测试下来,总体的文件大小比pb格式的还略小一些
优化效果
原始文件小2M,内存占用与文件大小完全一致,比pb略小
90个散文件加载时长降到25ms左右,如果打包成一个文件,4ms左右就可以完成加载
与机器CPU性能无关,只与文件io有关