几个常用Json组件的性能测试
上一篇文章中我已经介绍了JsonBuilder方案的整体思路以及一个版本的雏形代码,他现在已经是可以使用的了,但是因为是实时反射的,所以效率并不高。
鉴于几位博友对Json转换组件的性能有兴趣,我先放几个常用组件的测试结果以供参考。下一篇在详细介绍JsonBuilder的优化工作
测试用例
using System;
using System.Collections.Generic; /// <summary> 用户对象
/// </summary>
public class User
{
public static User TestUser()
{//这里我尽量构造一个看上去很复杂的对象,并且这个对象几乎涵盖了所有常用的类型
User user = new User();
user.UID = Guid.NewGuid();
user.Birthday = new DateTime(, , , , , );
user.IsDeleted = false;
user.Name = "blqw";
user.Sex = UserSex.Male;
user.LoginHistory = new List<DateTime>();
user.LoginHistory.Add(DateTime.Today.Add(new TimeSpan(, , )));
user.LoginHistory.Add(DateTime.Today.Add(new TimeSpan(, , )));
user.LoginHistory.Add(DateTime.Today.Add(new TimeSpan(, , )));
user.LoginHistory.Add(DateTime.Today.Add(new TimeSpan(, , )));
user.LoginHistory.Add(DateTime.Today.Add(new TimeSpan(, , )));
user.Info = new UserInfo();
user.Info.Address = "广东省广州市";
user.Info.ZipCode = ;
user.Info.Phone = new Dictionary<string, string>();
user.Info.Phone.Add("手机", "");
user.Info.Phone.Add("电话", "");
user.Info.Phone.Add("短号", "");
user.Info.Phone.Add("QQ", "");
user.Double = Double.NegativeInfinity;
// user.Self = user; //这里是用来测试循环引用的解析情况
return user;
} public User Self { get; set; }
//User self
/// <summary> 唯一ID
/// </summary>
public Guid UID { get; set; }
/// <summary> 用户名称
/// </summary>
public string Name { get; set; }
/// <summary> 生日
/// </summary>
public DateTime Birthday { get; set; }
/// <summary> 性别
/// </summary>
public UserSex Sex { get; set; }
/// <summary> 是否删除标记
/// </summary>
public bool IsDeleted { get; set; }
/// <summary> 最近登录记录
/// </summary>
public List<DateTime> LoginHistory { get; set; }
/// <summary> 联系信息
/// </summary>
public UserInfo Info { get; set; }
public Double Double { get; set; }
}
/// <summary> 用户性别
/// </summary>
public enum UserSex
{
/// <summary> 男
/// </summary>
Male,
/// <summary> 女
/// </summary>
Female
}
/// <summary> 用户信息
/// </summary>
public class UserInfo
{
/// <summary> 地址
/// </summary>
public string Address { get; set; }
/// <summary> 联系方式
/// </summary>
public Dictionary<string, string> Phone { get; set; }
/// <summary> 邮政编码
/// </summary>
public int ZipCode { get; set; }
}
测试用例
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Reflection.Emit;
using System.Data;
using fastJSON;
using System.IO;
using System.Threading; namespace blqw
{
class Program
{ static void Main(string[] args)
{
int count = ;
var obj = User.TestUser();
TestJavaScriptSerializer(count, obj);
TestNewtonsoftJson(count, obj);
TestJayrockJson(count, obj);
TestFastJson(count, obj);
TestQuickJsonBuilder(count, obj);
TestJsonBuilder(count, obj);
} //测试QuickJsonBuilder性能
static void TestQuickJsonBuilder(int count, object obj)
{
Stopwatch sw = new Stopwatch(); Console.WriteLine();
Console.WriteLine("QuickJsonBuilder 每次" + count + " 共10次");
for (int j = ; j < ; j++)
{
sw.Restart();
for (int i = ; i < count; i++)
{
QuickJsonBuilder jb = new QuickJsonBuilder();
jb.ToJson(obj);
}
sw.Stop();
Console.Write(sw.ElapsedMilliseconds + "ms | ");
}
Console.WriteLine();
Console.WriteLine("结果:" + new QuickJsonBuilder().ToJson(obj));
Console.WriteLine("==============================================");
}
//测试FastJson性能
static void TestFastJson(int count, object obj)
{
Stopwatch sw = new Stopwatch();
JSONParameters p = new JSONParameters();
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 (int j = ; j < ; j++)
{
sw.Restart();
for (int i = ; 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性能
static void TestJayrockJson(int count, object obj)
{
Stopwatch sw = new Stopwatch(); Console.WriteLine();
Console.WriteLine("Jayrock.Json 每次" + count + " 共10次");
for (int j = ; j < ; j++)
{
sw.Restart();
for (int i = ; i < count; i++)
{
var writer = new Jayrock.Json.JsonTextWriter();
Jayrock.Json.Conversion.JsonConvert.Export(obj, writer);
string str = writer.ToString();
}
sw.Stop();
Console.Write(sw.ElapsedMilliseconds + "ms | ");
}
var w = new Jayrock.Json.JsonTextWriter();
Jayrock.Json.Conversion.JsonConvert.Export(obj, w); Console.WriteLine();
Console.WriteLine("结果:" + w.ToString());
Console.WriteLine("==============================================");
} static void TestNewtonsoftJson(int count, object obj)
{
Stopwatch sw = new Stopwatch(); Console.WriteLine();
Console.WriteLine("Newtonsoft.Json 每次" + count + " 共10次");
for (int j = ; j < ; j++)
{
sw.Restart();
for (int i = ; i < count; i++)
{
Newtonsoft.Json.JsonConvert.SerializeObject(obj);
}
sw.Stop();
Console.Write(sw.ElapsedMilliseconds + "ms | ");
}
var w = Newtonsoft.Json.JsonConvert.SerializeObject(obj); Console.WriteLine();
Console.WriteLine("结果:" + w.ToString());
Console.WriteLine("==============================================");
} static void TestJavaScriptSerializer(int count, object obj)
{ Stopwatch sw = new Stopwatch(); Console.WriteLine();
Console.WriteLine("JavaScriptSerializer 每次" + count + " 共10次");
for (int j = ; j < ; j++)
{
sw.Restart();
for (int i = ; i < count; i++)
{
new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(obj);
}
sw.Stop();
Console.Write(sw.ElapsedMilliseconds + "ms | ");
}
var w = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(obj); Console.WriteLine();
Console.WriteLine("结果:" + w.ToString());
Console.WriteLine("==============================================");
} //测试JsonBuilder性能
static void JsonBuilder(int count, object obj)
{
Stopwatch sw = new Stopwatch(); Console.WriteLine();
Console.WriteLine("QuickJsonBuilder 每次" + count + " 共10次");
for (int j = ; j < ; j++)
{
sw.Reset();
sw.Start();
for (int i = ; i < count; i++)
{
JsonBuilder jb = new JsonBuilder();
jb.ToJsonString(obj);
}
sw.Stop();
Console.Write(sw.ElapsedMilliseconds + "ms | ");
}
Console.WriteLine();
Console.WriteLine("结果:" + new JsonBuilder().ToJsonString(obj));
Console.WriteLine("==============================================");
} }
}
测试代码
测试方案1:微软自带的的 JavaScriptSerializer
引用组件:System.Web.Extensions(微软自带了,引用下就好)
string str = new System.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
string str = 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
JsonTextWriter jtw = new Jayrock.Json.JsonTextWriter();
Jayrock.Json.Conversion.JsonConvert.Export(User.TestUser(), jtw);
string str = 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
JSONParameters p = new JSONParameters();
p.EnableAnonymousTypes
= p.IgnoreCaseOnDeserialize
= p.ShowReadOnlyProperties
= p.UseEscapedUnicode
= p.UseExtensions
= p.UseFastGuid
= p.UseOptimizedDatasetSchema
= p.UseUTCDateTime
= p.UsingGlobalTypes
= false;//所有参数为false,执行速度最快 string str = fastJSON.JSON.Instance.ToJSON(User.TestUser(), p);
//{"Self":null,"UID":"6f50b429-5c13-4875-a29a-e4bd8d7b2772","Name":"blqw","Birthday":"1986-10-29 18:00:00","Sex":"Male","IsDeleted":false,"LoginHistory":["2013-08-22 08:00:00","2013-08-22 10:10:10","2013-08-22 12:33:56","2013-08-22 17:25:18","2013-08-22 23:06:59"],"Info":{"Address":"广东省广州市","Phone":{"手机":"18688888888","电话":"82580000","短号":"10086","QQ":"21979018"},"ZipCode":510000},"Double":-Infinity}
测试方案5,6:QuickJsonBuilder,JsonBuilder
ps:以上几种类型都不支持循环引用,如果有,直接抛出异常
说明:QuickJsonBuilder就是我上篇中介绍的JsonBuilder的终极形态
QuickJsonBuilder jb = new QuickJsonBuilder();
jb.ToJson(User.TestUser());
//{"Self":null,"UID":"6f50b429-5c13-4875-a29a-e4bd8d7b2772","Name":"blqw","Birthday":"1986-10-29 18:00:00","Sex":"Male","IsDeleted":false,"LoginHistory":["2013-08-22 08:00:00","2013-08-22 10:10:10","2013-08-22 12:33:56","2013-08-22 17:25:18","2013-08-22 23: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 | 0 | 0 | 0 | 0 | |
| Newtonsoft.Json | 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 | 7 | 7 | 8 | 7 | |
| Newtonsoft.Json | 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下有没有相应的组件
好吧 我自己的组件我就不做评价了
几个常用Json组件的性能测试的更多相关文章
- Java几种常用JSON库性能比较
本篇通过JMH来测试一下Java中几种常见的JSON解析库的性能. 每次都在网上看到别人说什么某某库性能是如何如何的好,碾压其他的库.但是百闻不如一见,只有自己亲手测试过的才是最值得相信的. JSON ...
- 【转载】 C#使用Newtonsoft.Json组件来反序列化字符串为对象
在Asp.Net网站开发的过程中,很多时候会遇到对象的序列化和反序列化操作,Newtonsoft.Json组件是专门用来序列化和反序列化操作的一个功能组件,引入这个DLL组件后,就可使用JsonCon ...
- 统一的Json组件和csv下载组件
java-web-common java-web-common Json组件 目标和用途 规范Json接口格式 Controller中一律返回Java object,组件将自动转换数据格式,满足Jso ...
- java后台常用json解析工具问题小结
若排版紊乱可查看我的个人博客原文地址 java后台常用json解析工具问题小结 这里不细究造成这些问题的底层原因,只是单纯的描述我碰到的问题及对应的解决方法 jackson将java对象转json字符 ...
- [转]MySQL常用Json函数和MySQL常用字符串函数
MySQL常用Json函数:https://www.cnblogs.com/waterystone/p/5626098.html MySQL常用字符串函数:https://www.cnblogs.co ...
- React Native常用第三方组件汇总--史上最全 之一
React Native 项目常用第三方组件汇总: react-native-animatable 动画 react-native-carousel 轮播 react-native-countdown ...
- Java常用排序算法及性能测试集合
测试报告: Array length: 20000 bubbleSort : 573 ms bubbleSortAdvanced : 596 ms bubbleSortAdvanced2 : 583 ...
- React Native常用第三方组件汇总--史上最全[转]
本文出处: http://blog.csdn.net/chichengjunma/article/details/52920137 React Native 项目常用第三方组件汇总: react-na ...
- 常用json解析库比较及选择 fastjson & gson
一.常用json解析库比较及选择 1.简介 fastjson和gson是目前比较常用的json解析库,并且现在我们项目代码中,也在使用这两个解析库. fastjson 是由阿里开发的,号称是处理jso ...
随机推荐
- FZU 2137 奇异字符串 后缀树组+RMQ
题目连接:http://acm.fzu.edu.cn/problem.php?pid=2137 题解: 枚举x位置,向左右延伸计算答案 如何计算答案:对字符串建立SA,那么对于想双延伸的长度L,假如有 ...
- 解决谷歌浏览器中的input背景色默认是黄色
input:-webkit-autofill { -webkit-box-shadow: 0 0 0px 1000px white inset !important; }
- 关于安装Apache之后,解析PHP的配置
需要配置四个地方 LoadModule php5_module modules/libphp5.soServerName localhost:80DirectoryIndex index.phpAdd ...
- hellocharts包的使用心得
首先将jar包导入Libs里面然后add进入于activity中调用 xml中加入布局 <lecho.lib.hellocharts.view.LineChartView android:id= ...
- Java工程师层级
- 如何用hypermesh生成包含interface的流体网格
在计算气动声学的时候,有些情况是需要我们提取流体计算的结果作为声学分析的边界条件,但是,有些流体网格因为物理模型的问题需要我们设定interface,恰恰你是机械,对流体了解一点,又不想花费太多时间来 ...
- HDU5937 Equation(DFS + 剪枝)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5937 Description Little Ruins is a studious boy, ...
- storm学习好文链接
大圆的那些事:http://www.cnblogs.com/panfeng412/tag/Storm/ xcc的博客:http://blog.csdn.net/damacheng/article/ca ...
- [深度学习大讲堂]从NNVM看2016年深度学习框架发展趋势
本文为微信公众号[深度学习大讲堂]特约稿,转载请注明出处 虚拟框架杀入 从发现问题到解决问题 半年前的这时候,暑假,我在SIAT MMLAB实习. 看着同事一会儿跑Torch,一会儿跑MXNet,一会 ...
- T-SQL Recipes之Common Function
在我们写SQL的时候,经常会用到许多内置方法,简化了我们许多代码,也提高了效率,这篇主要总结一些常用的方法. ISNULL VS COALESCE VS NULLIF 在SQL中,NULL值是比较特殊 ...