一、(微软自带)
#region using
private static string ObjectToStringOne(Object obj)
{
string str = System.Text.Json.JsonSerializer.Serialize(obj);
return str;
}
private static T StringToObjectOne<T>(string str)
{
T obj = System.Text.Json.JsonSerializer.Deserialize<T>(str);
return obj;
}
#endregion
二、(包)
#region using
private static string ObjectToStringTwo(Object obj)
{
string str = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
return str;
}
private static T StringToObjectTwo<T>(string str)
{
T obj = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(str);
return obj;
}
#endregion
三、(以数据流为中介)
#region using System.Runtime.Serialization.Json;
private static string ObjectToStringThree<T>(Object obj)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
MemoryStream ms = new MemoryStream();
serializer.WriteObject(ms, obj);
ms.Position = 0;
StreamReader sr = new StreamReader(ms, Encoding.UTF8);
string content_josn = sr.ReadToEnd();
sr.Close();
return content_josn;
}
private static T StringToObjectThree<T>(string str)
{
using (MemoryStream ms2 = new MemoryStream(Encoding.Unicode.GetBytes(str)))
{
DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(T));
T obj = (T)deserializer.ReadObject(ms2);
return obj;
}
}
#endregion
四、Nancy(包)
#region using Nancy.Json;
private static string ObjectToStringFour(Object obj)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
return jss.Serialize(obj);
}
private static T StringToObjectFour<T>(string str)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
return jss.Deserialize<T>(str);
}
#endregion
五、性能测试
1、使用Bogus生成假数据
[DataContract]
internal class Person
{
[DataMember]
public Guid Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Address { get; set; }
[DataMember]
public string Email { get; set; }
}
var studentgenerator = new Faker<Person>()
.RuleFor(o => o.Id, Guid.NewGuid)
.RuleFor(o => o.Name, f => f.Person.UserName)
.RuleFor(o => o.Address, f => f.Person.Address.City)
.RuleFor(o => o.Email, f => f.Person.Email);
var studentlist = studentgenerator.Generate(100000);
2、序列与反序列单个大对象
Stopwatch sw = new Stopwatch();
string str;
sw.Start();
str = ObjectToStringOne(studentlist);
StringToObjectOne<List<Person>>(str);
sw.Stop();
Console.WriteLine($"{sw.ElapsedTicks}");
sw.Reset();
sw.Start();
str = ObjectToStringTwo(studentlist);
StringToObjectTwo<List<Person>>(str);
sw.Stop();
Console.WriteLine($"{sw.ElapsedTicks}");
sw.Reset();
sw.Start();
str = ObjectToStringThree<List<Person>>(studentlist);
StringToObjectThree<List<Person>>(str);
sw.Stop();
Console.WriteLine($"{sw.ElapsedTicks}");
sw.Reset();
sw.Start();
str = ObjectToStringFour(studentlist);
StringToObjectFour<List<Person>>(str);
sw.Stop();
Console.WriteLine($"{sw.ElapsedTicks}");
3、序列与反序列多个小对象
Stopwatch sw = new Stopwatch();
string str;
sw.Start();
foreach(var item in studentlist)
{
str = ObjectToStringOne(item);
StringToObjectOne<Person>(str);
}
sw.Stop();
Console.WriteLine($"{sw.ElapsedTicks}");
sw.Reset();
sw.Start();
foreach (var item in studentlist)
{
str = ObjectToStringTwo(item);
StringToObjectTwo<Person>(str);
}
sw.Stop();
Console.WriteLine($"{sw.ElapsedTicks}");
sw.Reset();
sw.Start();
foreach (var item in studentlist)
{
str = ObjectToStringThree<Person>(item);
StringToObjectThree<Person>(str);
}
sw.Stop();
Console.WriteLine($"{sw.ElapsedTicks}");
sw.Reset();
sw.Start();
foreach (var item in studentlist)
{
str = ObjectToStringFour(item);
StringToObjectFour<Person>(str);
}
sw.Stop();
Console.WriteLine($"{sw.ElapsedTicks}");
六、测试结果
1. 测试版本
方法 |
版本 |
1 |
.Net Core 3.1 |
2 |
13.0.2 |
3 |
.Net Core 3.1 |
4 |
2.0.0 |
2. 结果
类数量 |
序列与反序列单个大对象 |
序列与反序列多个小对象 |
1000 |
4>3>1>2 |
2>3>4>1 |
10000 |
1>3>4>2 |
2>4=3>1 |
100000 |
1>3>2>4 |
2>3>4>1 |
3.结论
对应的数据代表方法名,越大代表性能越好用时越短
- 在序列与反序列多个小对象的场景下,1方法性能最差,2方法性能最好。
- 在序列与反序列多单个大对象的场景下,对象越大,1方法的性能优势越明显,其次是3方法。
- 具体使用哪种方法要根据应用场景的对象大小和使用频率决定。
七、参考文章
1.测试方案参考
2.序列化方式参考1
3.序列化方式参考2
4.测试结果参考
5.假数据生成器
6.Bogus的使用方法