And*_*rew 2 c# json dynamic json.net
搜索互联网时找不到正确的答案...
我JSON收到了来自服务器的数据。每次的格式都可能不同,因此我必须使用动态对象。当前在我们的项目中,我们正在使用库中的JToken类型Newtonsoft.JSON,但是如果我们看一下它的内部结构,恐怕它有很多装箱/拆箱的情况,这是不好的-我们应该使用尽可能少的内存,因为移动应用程序。
因此,问题是:使用dynamic类型c#本身更好(是的,尽管它也具有装箱/拆箱功能)还是它们之间没有区别?它们如何利用内存使用?有人对它们进行过基准测试吗?
也许对于他们两个都有一些好的选择?
提前致谢
因此,似乎没有人做与我的问题有关的事情,并且我做了自己的测试,现在我不愿分享自己的结果。希望他们会有所帮助。
首先,我想说我对某些结果感到非常震惊和惊讶。
首先是我的测试机配置:
测试非常简单:有一个json字符串,其大小存储在文件4.54 kB中。我运行100个测试,每个测试创建1000个指定类型的对象(动态/ JToken / JContainer)。在每次测试期间,我都会计算分配给这1000个对象的实际内存量,以及将json-string解析为指定对象类型所需的时间。完成所有测试后,我计算平均已用内存量和每个测试集的平均时间。通过基于公式的简单算法对平均计数器进行计数for 0 < i < n, S += SUM(i), a = S/n,其中S-所有计数器的总和n-测试量(100)a-平均计数器。内存使用情况由Process和计算GC
现在最有趣的部分(IMO)-我的基准测试结果:)
首先,我使用Newtonsoft.JSON内置方法JToken.Parse()和进行了测试JContainer.Parse()。这两个集合都产生了与预期相同的结果(因为JContainer是的嵌套类型JToken):
JToken / JContainer
平均 记忆体使用量:25.7 MB
平均 解析时间:223毫秒
很简单 现在我运行了testsusing JsonConver.Deserialize<T>(string json)方法,将我的json数据反序列化为相同的JToken/JContainer类型,这让我感到惊讶
JsonConver.Deserialize(string json)到JToken / JContainer
平均内存使用量:22.0 MB
平均 解析时间:223毫秒
因此,就我个人而言,Parse()用于JToken/JContainer生成对象的方法比使用JsonConver.Deserialize<T>()方法分配更多的内存不足为奇。真是出乎意料。
这部分的最后一组测试的dynamic类型使用相同的JsonConver.Deserialize<T>(string json)方法:
JsonConver.Deserialize(字符串json)动态
平均 记忆体使用量:22.1 MB
平均解析时间:224毫秒
老实说,我期望得到一些不同的结果,但是似乎这JToken只是一个包装,dynamic这就是为什么他们使用相同的内存量并花费相同的解析时间。
万事俱备,但总会有一些“条件”。我用于测试的json数据的大小很小(当然,我们总是尝试通过网络发送尽可能少的数据)。我必须使用的真实对象实例具有更大的大小,为了对真实数据真正满意,我运行了另一个测试集。现在,大小为270 kB的真实对象(在第一组中为4.54 kB)。结果真的让我震惊。JToken/JContainer的Parse()方法失败了!!!我的8 GB RAM计算机上出现内存不足异常!!!在我附近打开任务管理器后,我看到测试程序的内存超过2 GB !!!我以为那是测试的终点,但我是个有野心的家伙,所以我继续。运行测试JsonConver.Deserialize<T>()为我带来了更多成功:
270kB JsonConver.Deserialize()
平均 记忆体使用量:1.63 GB
平均解析时间:20秒
是的,它是正确的:1.63 GB和20秒的时间将1000个对象解析为JToken/JContainer类型。与the一起工作dynamic给了我相同的结果,所以我不再复制它们
如果我没有尝试使用对象解析来测试json,则这些测试将不完整。所以我创建了一个描述我的json结构和使用JsonConver.Deserialize<T>()方法的类:
JsonConver.Deserialize()解析为POCO对象
平均 记忆体使用量:72 MB
平均 解析时间:7.5。s
1000个POCO对象为72 MB,而动态数据为1.63Gb。
PS。而不是得出结论……当然,我们总是尝试使用对象来处理代码中的数据,但是有时我们必须处理动态问题。现在您可以看到C#中对象的效率如何。而且,我建议您不要使用JToken.Parse(),为自己节省一些内存。引入IMO,OOP可以真正帮助开发人员并使我们的夜晚梦想成真。它的工作!:)
PPS。所有有兴趣看到我的测试解决方案的人-欢迎访问github :)
| 归档时间: |
|
| 查看次数: |
950 次 |
| 最近记录: |