C# 几个常用 Json 组件的性能测试
鉴于几位博友对Json转换组件的性能有兴趣,我先放几个常用组件的测试结果以供参考。下一篇在详细介绍JsonBuilder的优化工作
usingSystem;
usingSystem.Collections.Generic;
///<summary>用户对象
///</summary>
publicclassUser
{
publicstaticUserTestUser()
{//这里我尽量构造一个看上去很复杂的对象,并且这个对象几乎涵盖了所有常用的类型
Useruser=newUser();
user.UID=Guid.NewGuid();
user.Birthday=newDateTime(1986,10,29,18,00,00);
user.IsDeleted=false;
user.Name="blqw";
user.Sex=UserSex.Male;
user.LoginHistory=newList<DateTime>();
user.LoginHistory.Add(DateTime.Today.Add(newTimeSpan(8,00,00)));
user.LoginHistory.Add(DateTime.Today.Add(newTimeSpan(10,10,10)));
user.LoginHistory.Add(DateTime.Today.Add(newTimeSpan(12,33,56)));
user.LoginHistory.Add(DateTime.Today.Add(newTimeSpan(17,25,18)));
user.LoginHistory.Add(DateTime.Today.Add(newTimeSpan(23,06,59)));
user.Info=newUserInfo();
user.Info.Address="广东省广州市";
user.Info.ZipCode=510000;
user.Info.Phone=newDictionary<string,string>();
user.Info.Phone.Add("手机","18688888888");
user.Info.Phone.Add("电话","82580000");
user.Info.Phone.Add("短号","10086");
user.Info.Phone.Add("QQ","21979018");
user.Double=Double.NegativeInfinity;
//user.Self=user;//这里是用来测试循环引用的解析情况
returnuser;
}
publicUserSelf{get;set;}
//Userself
///<summary>唯一ID
///</summary>
publicGuidUID{get;set;}
///<summary>用户名称
///</summary>
publicstringName{get;set;}
///<summary>生日
///</summary>
publicDateTimeBirthday{get;set;}
///<summary>性别
///</summary>
publicUserSexSex{get;set;}
///<summary>是否删除标记
///</summary>
publicboolIsDeleted{get;set;}
///<summary>最近登录记录
///</summary>
publicList<DateTime>LoginHistory{get;set;}
///<summary>联系信息
///</summary>
publicUserInfoInfo{get;set;}
publicDoubleDouble{get;set;}
}
///<summary>用户性别
///</summary>
publicenumUserSex
{
///<summary>男
///</summary>
Male,
///<summary>女
///</summary>
Female
}
///<summary>用户信息
///</summary>
publicclassUserInfo
{
///<summary>地址
///</summary>
publicstringAddress{get;set;}
///<summary>联系方式
///</summary>
publicDictionary<string,string>Phone{get;set;}
///<summary>邮政编码
///</summary>
publicintZipCode{get;set;}
}
测试用例
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
usingSystem.Diagnostics;
usingSystem.Reflection.Emit;
usingSystem.Data;
usingfastJSON;
usingSystem.IO;
usingSystem.Threading;
namespaceblqw
{
classProgram
{
staticvoidMain(string[]args)
{
intcount=10000;
varobj=User.TestUser();
TestJavaScriptSerializer(count,obj);
TestNewtonsoftJson(count,obj);
TestJayrockJson(count,obj);
TestFastJson(count,obj);
TestQuickJsonBuilder(count,obj);
TestJsonBuilder(count,obj);
}
//测试QuickJsonBuilder性能
staticvoidTestQuickJsonBuilder(intcount,objectobj)
{
Stopwatchsw=newStopwatch();
Console.WriteLine();
Console.WriteLine("QuickJsonBuilder每次"+count+"共10次");
for(intj=0;j<10;j++)
{
sw.Restart();
for(inti=0;i<count;i++)
{
QuickJsonBuilderjb=newQuickJsonBuilder();
jb.ToJson(obj);
}
sw.Stop();
Console.Write(sw.ElapsedMilliseconds+"ms|");
}
Console.WriteLine();
Console.WriteLine("结果:"+newQuickJsonBuilder().ToJson(obj));
Console.WriteLine("==============================================");
}
//测试FastJson性能
staticvoidTestFastJson(intcount,objectobj)
{
Stopwatchsw=newStopwatch();
JSONParametersp=newJSONParameters();
p.EnableAnonymousTypes
=p.IgnoreCaseOnDeserialize
=p.ShowReadOnlyProperties
=p.UseEscapedUnicode
=p.UseExtensions
=p.UseFastGuid
=p.UseOptimizedDatasetSchema
=p.UseUTCDateTime
=p.UsingGlobalTypes
=false;
Console.WriteLine();
Console.WriteLine("fastJSON.NET每次"+count+"共10次");
for(intj=0;j<10;j++)
{
sw.Restart();
for(inti=0;i<count;i++)
{
fastJSON.JSON.Instance.ToJSON(obj,p);
}
sw.Stop();
Console.Write(sw.ElapsedMilliseconds+"ms|");
}
Console.WriteLine();
Console.WriteLine("结果:"+fastJSON.JSON.Instance.ToJSON(obj,p));
Console.WriteLine("==============================================");
}
//测试JayrockJson性能
staticvoidTestJayrockJson(intcount,objectobj)
{
Stopwatchsw=newStopwatch();
Console.WriteLine();
Console.WriteLine("Jayrock.Json每次"+count+"共10次");
for(intj=0;j<10;j++)
{
sw.Restart();
for(inti=0;i<count;i++)
{
varwriter=newJayrock.Json.JsonTextWriter();
Jayrock.Json.Conversion.JsonConvert.Export(obj,writer);
stringstr=writer.ToString();
}
sw.Stop();
Console.Write(sw.ElapsedMilliseconds+"ms|");
}
varw=newJayrock.Json.JsonTextWriter();
Jayrock.Json.Conversion.JsonConvert.Export(obj,w);
Console.WriteLine();
Console.WriteLine("结果:"+w.ToString());
Console.WriteLine("==============================================");
}
staticvoidTestNewtonsoftJson(intcount,objectobj)
{
Stopwatchsw=newStopwatch();
Console.WriteLine();
Console.WriteLine("Newtonsoft.Json每次"+count+"共10次");
for(intj=0;j<10;j++)
{
sw.Restart();
for(inti=0;i<count;i++)
{
Newtonsoft.Json.JsonConvert.SerializeObject(obj);
}
sw.Stop();
Console.Write(sw.ElapsedMilliseconds+"ms|");
}
varw=Newtonsoft.Json.JsonConvert.SerializeObject(obj);
Console.WriteLine();
Console.WriteLine("结果:"+w.ToString());
Console.WriteLine("==============================================");
}
staticvoidTestJavaScriptSerializer(intcount,objectobj)
{
Stopwatchsw=newStopwatch();
Console.WriteLine();
Console.WriteLine("JavaScriptSerializer每次"+count+"共10次");
for(intj=0;j<10;j++)
{
sw.Restart();
for(inti=0;i<count;i++)
{
newSystem.Web.Script.Serialization.JavaScriptSerializer().Serialize(obj);
}
sw.Stop();
Console.Write(sw.ElapsedMilliseconds+"ms|");
}
varw=newSystem.Web.Script.Serialization.JavaScriptSerializer().Serialize(obj);
Console.WriteLine();
Console.WriteLine("结果:"+w.ToString());
Console.WriteLine("==============================================");
}
//测试JsonBuilder性能
staticvoidJsonBuilder(intcount,objectobj)
{
Stopwatchsw=newStopwatch();
Console.WriteLine();
Console.WriteLine("QuickJsonBuilder每次"+count+"共10次");
for(intj=0;j<10;j++)
{
sw.Reset();
sw.Start();
for(inti=0;i<count;i++)
{
JsonBuilderjb=newJsonBuilder();
jb.ToJsonString(obj);
}
sw.Stop();
Console.Write(sw.ElapsedMilliseconds+"ms|");
}
Console.WriteLine();
Console.WriteLine("结果:"+newJsonBuilder().ToJsonString(obj));
Console.WriteLine("==============================================");
}
}
}
测试代码
测试方案1:微软自带的的JavaScriptSerializer
引用组件:System.Web.Extensions(微软自带了,引用下就好)
stringstr=newSystem.Web.Script.Serialization.JavaScriptSerializer().Serialize(User.TestUser());
//{"Self":null,"UID":"6f50b429-5c13-4875-a29a-e4bd8d7b2772","Name":"blqw","Birthday":"\/Date(530964000000)\/","Sex":0,"IsDeleted":false,"LoginHistory":["\/Date(1377129600000)\/","\/Date(1377137410000)\/","\/Date(1377146036000)\/","\/Date(1377163518000)\/","\/Date(1377184019000)\/"],"Info":{"Address":"广东省广州市","Phone":{"手机":"18688888888","电话":"82580000","短号":"10086","QQ":"21979018"},"ZipCode":510000},"Double":-Infinity}
测试方案2:Newtonsoft.Json
引用组件:Newtonsoft.Json.Net35.dll
stringstr=Newtonsoft.Json.JsonConvert.SerializeObject(User.TestUser());
//{"Self":null,"UID":"6f50b429-5c13-4875-a29a-e4bd8d7b2772","Name":"blqw","Birthday":"\/Date(530964000000+0800)\/","Sex":0,"IsDeleted":false,"LoginHistory":["\/Date(1377129600000+0800)\/","\/Date(1377137410000+0800)\/","\/Date(1377146036000+0800)\/","\/Date(1377163518000+0800)\/","\/Date(1377184019000+0800)\/"],"Info":{"Address":"广东省广州市","Phone":{"手机":"18688888888","电话":"82580000","短号":"10086","QQ":"21979018"},"ZipCode":510000},"Double":-Infinity}
测试方案3:Jayrock.Json
引用组件:Jayrock.Json.dll
JsonTextWriterjtw=newJayrock.Json.JsonTextWriter();
Jayrock.Json.Conversion.JsonConvert.Export(User.TestUser(),jtw);
stringstr=jtw.ToString();
//{"uID":"6f50b429-5c13-4875-a29a-e4bd8d7b2772","name":"blqw","birthday":"1986-10-29T18:00:00.0000000+08:00","sex":"Male","isDeleted":false,"loginHistory":["2013-08-22T08:00:00.0000000+08:00","2013-08-22T10:10:10.0000000+08:00","2013-08-22T12:33:56.0000000+08:00","2013-08-22T17:25:18.0000000+08:00","2013-08-22T23:06:59.0000000+08:00"],"info":{"address":"广东省广州市","phone":{"手机":"18688888888","电话":"82580000","短号":"10086","QQ":"21979018"},"zipCode":510000},"double":-Infinity}
测试方案4:fastJSON.NET
引用组件:fastJSON.dll
JSONParametersp=newJSONParameters();
p.EnableAnonymousTypes
=p.IgnoreCaseOnDeserialize
=p.ShowReadOnlyProperties
=p.UseEscapedUnicode
=p.UseExtensions
=p.UseFastGuid
=p.UseOptimizedDatasetSchema
=p.UseUTCDateTime
=p.UsingGlobalTypes
=false;//所有参数为false,执行速度最快
stringstr=fastJSON.JSON.Instance.ToJSON(User.TestUser(),p);
//{"Self":null,"UID":"6f50b429-5c13-4875-a29a-e4bd8d7b2772","Name":"blqw","Birthday":"1986-10-2918:00:00","Sex":"Male","IsDeleted":false,"LoginHistory":["2013-08-2208:00:00","2013-08-2210:10:10","2013-08-2212:33:56","2013-08-2217:25:18","2013-08-2223:06:59"],"Info":{"Address":"广东省广州市","Phone":{"手机":"18688888888","电话":"82580000","短号":"10086","QQ":"21979018"},"ZipCode":510000},"Double":-Infinity}
测试方案5,6:QuickJsonBuilder,JsonBuilder
ps:以上几种类型都不支持循环引用,如果有,直接抛出异常
说明:QuickJsonBuilder就是我上篇中介绍的JsonBuilder的终极形态
QuickJsonBuilderjb=newQuickJsonBuilder();
jb.ToJson(User.TestUser());
//{"Self":null,"UID":"6f50b429-5c13-4875-a29a-e4bd8d7b2772","Name":"blqw","Birthday":"1986-10-2918:00:00","Sex":"Male","IsDeleted":false,"LoginHistory":["2013-08-2208:00:00","2013-08-2210:10:10","2013-08-2212:33:56","2013-08-2217:25:18","2013-08-2223:06:59"],"Info":{"Address":"广东省广州市","Phone":{"手机":"18688888888","电话":"82580000","短号":"10086","QQ":"21979018"},"ZipCode":510000},"Double":-Infinity}
ps:当Self指向自己本身的时候,将返回"Self":undefined用以区分空对象
测试方案7:ServiceStack.Text
引用组件:ServiceStack.Text.dll抱歉我只找到4.0的
这个是后来补上的,测试代码中没有这个...
User.TestUser().ToJson();
//{"UID":"48d4624ad0c8475094d00fc769c7129f","Name":"blqw","Birthday":"\/Date(530964000000+0800)\/","Sex":"Male","IsDeleted":false,"LoginHistory":["\/Date(1377129600000+0800)\/","\/Date(1377137410000+0800)\/","\/Date(1377146036000+0800)\/","\/Date(1377163518000+0800)\/","\/Date(1377184019000+0800)\/"],"Info":{"Address":"广东省广州市","Phone":{"手机":"18688888888","电话":"82580000","短号":"10086","QQ":"21979018"},"ZipCode":510000},"Double":-Infinity}
ps:依然不支持循环引用,抛出堆栈异常
测试结果(单位"毫秒")
循环次数 | 测试组件 | 第一轮 | 第二轮 | 第三轮 | 第四轮 | 第五轮 |
1次 | JavaScriptSerializer |
12 |
0 | 0 | 0 | 0 |
Newtonsoft.Json | 208 | 0 | 0 | 0 | 0 | |
Jayrock.Json | 85 | 0 | 0 | 0 | 0 | |
fastJSON.NET | 47 | 0 | 0 | 0 | 0 | |
QuickJsonBuilder | 37 | 0 | 0 | 0 | 0 | |
JsonBuilder | 22 | 0 | 0 | 0 | 0 | |
ServiceStack.Text | 138 | 0 | 0 | 0 | 0 | |
100次 | JavaScriptSerializer | 23 | 7 | 7 | 8 | 7 |
Newtonsoft.Json | 201 | 2 | 3 | 2 | 2 | |
Jayrock.Json | 77 | 8 | 9 | 9 | 8 | |
fastJSON.NET | 41 | 1 | 1 | 1 | 1 | |
QuickJsonBuilder | 36 | 1 | 1 | 1 | 1 | |
JsonBuilder | 26 | 3 | 4 | 3 | 3 | |
ServiceStack.Text | 139 | 2 | 2 | 2 | 2 | |
10000次 | JavaScriptSerializer | 765 | 751 | 752 | 751 | 749 |
Newtonsoft.Json | 437 | 253 | 251 | 248 | 243 | |
Jayrock.Json | 967 | 905 | 965 | 913 | 952 | |
fastJSON.NET | 239 | 181 | 200 | 167 | 166 | |
QuickJsonBuilder | 171 | 128 | 132 | 136 | 129 | |
JsonBuilder | 418 | 386 | 388 | 391 | 360 | |
ServiceStack.Text | 367 | 216 | 224 | 238 | 223 |
测试结果仅供参考
总结
可以看出基本所有组件在第一轮用时都是最长的,应该是在处理一些初始化和缓存的工作。
所以呢,我特别给出了1次的循环结果,
JavaScriptSerializer 可以看出在100次以内的时候微软的还是有一些优势的,随着次数增加性能就渐渐跟不上了
Newtonsoft.Json一直表现平平啊,没有特别突出就地方,就跟JsonBuilder比性能也没有好到那里去
Jayrock.Json 是昨天一位博友告诉我的,据说是淘宝sdk在用的,性能只能说,好差。。。
fastJSON.NET 确实是所有组件中最快的,QuickJsonBuilder也从中借鉴了一些处理方式
ServiceStack.Text 中规中矩吧比Newtonsoft.Json好一点点.就是我只找到4.0的拓展方法,不知道2.0下有没有相应的组件
好吧 我自己的组件我就不做评价了
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。