.NET性能系列文章二:Newtonsoft.Json vs. System.Text.Json( 二 )


[Benchmark(Baseline = true)]public void NewtonsoftSerializeMuchData(){foreach (var user in testUsers){_ = Newtonsoft.Json.JsonConvert.SerializeObject(user);}}[Benchmark]public void MicrosoftSerializeMuchData(){foreach (var user in testUsers){_ = System.Text.Json.JsonSerializer.Serialize(user);}}在我的机器上,这个基准测试导致了以下结果:
MethodCountMeanRatioAllocatedAlloc RatioNewtonsoftSerializeMuchData100008.087 ms1.0017.14 MB1.00MicrosoftSerializeMuchData100003.944 ms0.493.64 MB0.21

.NET性能系列文章二:Newtonsoft.Json vs. System.Text.Json

文章插图
我们可以看到对于许多小对象来说,性能又快了近100% 。不仅System.Text.Json的性能比Newtonsoft快了一倍,而且堆分配的内存甚至少了5倍! 正如我在以前的文章中提到的,节省堆内存甚至比速度更重要,你在这里看到了 。堆内存最终将不得不被垃圾回收,这将阻塞你的整个应用程序的执行 。
反序列化测试在现实世界的应用中,你不仅要序列化,还要从JSON序列化的字符串中反序列化对象 。在下面的基准中,我们将再次使用Bogus,创建一组用户,但这次我们要把它们序列化为一个大的字符串,用于大数据对象,并把许多小数据对象序列化为List<string>
private string serializedTestUsers;private List<string> serializedTestUsersList = new();[GlobalSetup]public void GlobalSetup(){var faker = new Faker<User>().CustomInstantiator(f => new User(Guid.NewGuid(),f.Name.FirstName(),f.Name.LastName(),f.Name.FullName(),f.Internet.UserName(f.Name.FirstName(), f.Name.LastName()),f.Internet.Email(f.Name.FirstName(), f.Name.LastName())));var testUsers = faker.Generate(Count);serializedTestUsers = JsonSerializer.Serialize(testUsers);foreach (var user in testUsers.Select(u => JsonSerializer.Serialize(u))){serializedTestUsersList.Add(user);}}反序列化大对象第一个反序列化基准将一个大的JSON字符串反序列化为相应的.NET对象 。在这种情况下,它又是List<User>,我们在前面的例子中也使用了它 。
[Benchmark(Baseline = true)]public void NewtonsoftDeserializeBigData() =>_ = Newtonsoft.Json.JsonConvert.DeserializeObject<List<User>>(serializedTestUsers);[Benchmark]public void MicrosoftDeserializeBigData() =>_ = System.Text.Json.JsonSerializer.Deserialize<List<User>>(serializedTestUsers);在我的机器上运行这些基准测试,得出以下结果:
MethodCountMeanRatioAllocatedAlloc RatioNewtonsoftDeserializeBigData1000021.20 ms1.0010.55 MB1.00MicrosoftDeserializeBigData1000012.12 ms0.576.17 MB0.59
.NET性能系列文章二:Newtonsoft.Json vs. System.Text.Json

文章插图
就性能而言,微软仍然远远领先于Newtonsoft 。然而,我们可以看到,Newtonsoft并没有慢一半,而是慢了40%左右,这在与序列化基准的直接比较中是一个进步 。
反序列化许多小对象本章的最后一个基准是许多小对象的反序列化 。在这里,我们使用我们在上面的GlobalSetup()方法中初始化的List<string>,在一个循环中反序列化数据对象:
[Benchmark(Baseline = true)]public void NewtonsoftDeserializeMuchData(){foreach (var user in serializedTestUsersList){_ = Newtonsoft.Json.JsonConvert.DeserializeObject<User>(user);}}[Benchmark]public void MicrosoftDeserializeMuchData(){foreach (var user in serializedTestUsersList){_ = System.Text.Json.JsonSerializer.Deserialize<User>(user);}}其结果甚至比相关的序列化基准更令人吃惊:
MethodCountMeanRatioAllocatedAlloc RatioNewtonsoftDeserializeMuchData1000015.577 ms1.0035.54 MB1.00MicrosoftDeserializeMuchData100007.916 ms0.514.8 MB0.14
.NET性能系列文章二:Newtonsoft.Json vs. System.Text.Json

文章插图

经验总结扩展阅读