客户端配置文件优化策略
- 作者:admin
- /
- 时间:2017年09月20日
- /
- 浏览:9912 次
- /
- 分类:厚积薄发
配置文件的读取也是性能优化中的重要环节,笔者对市面上大部分Json库的性能进行比较测试,包括:LitJson、System.Net.Json、FastJson、Newtonsoft.Json以及二进制格式,得出了优化策略,值得大家分享借鉴。
前要
一般游戏策划给的配置都是用Excel,最后给程序是CSV、或者是转换成Json和二进制格式。本次测试中比对了市面上大部分Json库的性能比较,包括:LitJson、System.Net.Json、FastJson、Newtonsoft.Json以及二进制格式。
其中,Json库中在全部同步读取解析最优秀的是Newtonsoft.json,GC以及速度最快。最差的是System.Net.Json,GC竟然高达100多MB,下文将介绍详细的测试过程。
一、Json库性能比较
测试方式:IO全部读取完成,测试平台为同一台PC机器,只测试其解析耗时以及GC量。
1、LitJson
GC量:15.7 MB
读取速度:494.61 ms
性能走势图:
2、FastJson
GC量:25.4 MB
耗时:199.72 ms
性能走势图:
3、System.Net.Json
GC量:151.2 MB
耗时:1657.7 ms
性能走势图:
4、NewtonJson
GC量: 7.7 MB
耗时:266.84 ms
性能走势图:
二、二进制读取测试
一般配置文件都分KEY和VALUE两部分,我们也将二进制数据也分为KEY和VALUE两部分保存,文件结构:
文件头(包括信息以及有效性标识)
—————————————————————————
数据VALUE部分
—————————————————————————
数据KEY部分
—————————————————————————
测试分为以下四种:只读取二进制KEY部分,二进制全部读取,二进制采用协程分步骤全部读取(测试中,默认每次读取500条数据,读完KEY,再读取VALUE),以及协程只读取KEY部分。
1、只读取二进制KEY部分
GC量:1.6 MB
耗时:10.06 ms
性能走势图:
2、二进制全部读取
GC量:6.5 MB
耗时:119.41 ms
性能走势图:
3、协程每次500条,全部读取
GC最高峰值:462.5 KB
耗时最高峰值:17.06 ms
回调全部读取完成消耗时间:
性能走势图:
4、协程只读取KEY
GC最高峰值:0.7 MB
耗时最高峰值:13.97 ms
回调全部读取完成消耗时间:
性能走势图:
三、Json库测试结论
1.NewtonJson库的GC量以及耗时最低,最差是System.Net.Json。
2.其中GC量大的原因是:System.Text.Encoding.UTF8.GetString函数,以及Json库内部字符串处理,本身IO读取产生的GC量相对比较小。
四、二进制优化策略
1.常用小配置文件可以采用一次性将KEY和VALUE全部读取;
2.数据列不是很多但数据量中等的配置,可以采用只读取KEY,用到取VALUE再读取策略;
3.数据列很多并且数据量很大的配置,可以采用全部异步,预加载的方式优化;
4.采用预加载的方式,可以将配置文件IO部分和解析部分执行分开,先IO异步预加载完,再执行解析,尽量将内存峰值降低,防止因为配置文件导致堆内存过高。
五、示例工程
地址:https://github.com/billwillman/NsConfigLib
1.考虑到很多项目都是Json格式,示例工程中,我们采用尽量兼容Json的结构方式,封装了一个ConfigDictionary类,用于针对模拟一部分Dictionary的操作,隔离掉解析操作。
2.支持三种Json定义方式的转换,Dictionary<KEY, Vo>、Dictionary<KEY, List
3.使用方式很简单,Json解析方式,以LITJson为例:
LitJson.JsonMapper.ToObject<Dictionary<string, List<VO>>>(str);
ConfigDictioanry示例
Dictionary<KEY, Vo>对应ConfigVoMap<KEY, Vo>
Dictionary<KEY, List<Vo>对应ConfigVoListMap<KEY, Vo>
Dictionary<KEY1, Dictionary<KEY2, Vo>对应ConfigVoMapMap<KEY1, KEY2, Vo>
ConfigVoListMap<KEY, Vo> map = new ConfigVoListMap<KEY, Vo>();
// 读取全部:
map .LoadFromTextAsset
map.LoadFromBytes
// 预加载方式
map.Preload(m_FileName, m_Mono, OnEnd, OnProcess);
- 测试场景:
Untitled和Test1场景均是测试场景分别测试List结构和Dictionary结构。
这是侑虎科技第303篇原创文章,感谢作者故国之晚秋供稿,欢迎转发分享,未经作者授权请勿转载。当然,如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:793972859)
作者GitHub:https://github.com/billwillman/NsConfigLib,作者也是U Sparkle活动参与者,UWA欢迎更多开发朋友加入U Sparkle开发者计划,这个舞台有你更精彩!
没有报错啊
你这个工程运行都报错啊, LitJson.JsonMapper.ToObject(asset.text);
没有报错,刚5.3.8打开看了