Skip to content

Commit 92382bb

Browse files
committed
Add SystemTextJson JsonSerializerContext Benchmarks
1 parent f2dfcbe commit 92382bb

File tree

5 files changed

+257
-2
lines changed

5 files changed

+257
-2
lines changed

src/.editorconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,6 +1579,14 @@ resharper_indent_nested_while_stmt = true
15791579
resharper_indent_raw_literal_string = do_not_change
15801580
resharper_outdent_statement_labels = true
15811581

1582+
[*{Benchmark,Benchmarks}.cs]
1583+
# CA1707: Identifiers should not contain underscores
1584+
dotnet_diagnostic.CA1707.severity = none
1585+
# CRR0035 - No CancellationToken parameter in the asynchronous method
1586+
dotnet_diagnostic.CRR0035.severity = none
1587+
# CA1822: Mark members as static
1588+
dotnet_diagnostic.CA1822.severity = none
1589+
15821590
[*{Test,Tests}.cs]
15831591
# CA1707: Identifiers should not contain underscores
15841592
dotnet_diagnostic.CA1707.severity = none

src/plugins/NewtonsoftJsonTest/NewtonsoftJsonTest.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
<ItemGroup>
2121
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
22+
<PackageReference Include="BenchmarkDotNet" Version="0.15.2" />
2223
</ItemGroup>
2324

2425
</Project>

src/plugins/NewtonsoftJsonTest/Program.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using BenchmarkDotNet.Running;
2+
13
namespace NewtonsoftJsonTest;
24

35
internal sealed class Program
@@ -20,8 +22,10 @@ private static void Main(string[] args)
2022
//SystemTextJsonTest.GetonlyProp_DeserializeWithJsonInclude_IsNotAssigned();
2123
//SystemTextJsonTest.GetonlyProp_DeserializeWithJsonConstructor_IsAssigned();
2224

23-
SystemTextJsonTestGeneratorTest.SerializeTest();
24-
SystemTextJsonTestGeneratorTest.DeserializeTest();
25+
//SystemTextJsonTestGeneratorTest.SerializeTest();
26+
//SystemTextJsonTestGeneratorTest.DeserializeTest();
27+
28+
BenchmarkRunner.Run<SystemTextJsonBenchmarks>();
2529
}
2630

2731
#endregion
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
using BenchmarkDotNet.Attributes;
2+
using System.Text.Json;
3+
using System.Text.Json.Serialization;
4+
5+
namespace NewtonsoftJsonTest;
6+
7+
//[SimpleJob]
8+
[MemoryDiagnoser]
9+
public class SystemTextJsonBenchmarks
10+
{
11+
// Adjust buffer size
12+
private readonly JsonSerializerOptions _optionsBuffer = new()
13+
{
14+
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
15+
DefaultBufferSize = 2 * 1024 * 1024
16+
};
17+
18+
#region Methods
19+
20+
[Benchmark]
21+
public async Task MyDto()
22+
{
23+
await JsonSerializer.SerializeAsync(Stream.Null, TestData.Instance.WithPlainData(), MyContext.Default.ListMyDto);
24+
}
25+
26+
[Benchmark]
27+
public async Task MyDtoBuffer()
28+
{
29+
await JsonSerializer.SerializeAsync(
30+
Stream.Null,
31+
TestData.Instance.WithPlainData(),
32+
MyContextLargeBuffer.Default.ListMyDto);
33+
}
34+
35+
[Benchmark]
36+
public async Task MyDtoNoSG()
37+
{
38+
await JsonSerializer.SerializeAsync(Stream.Null, TestData.Instance.WithPlainData(), _optionsBuffer);
39+
}
40+
41+
[Benchmark]
42+
public async Task MyDtoLarge()
43+
{
44+
await JsonSerializer.SerializeAsync(
45+
Stream.Null,
46+
TestData.Instance.WithLargeData(),
47+
MyContext.Default.ListMyDtoLarge);
48+
}
49+
50+
[Benchmark]
51+
public async Task MyDtoLargeBuffer()
52+
{
53+
await JsonSerializer.SerializeAsync(
54+
Stream.Null,
55+
TestData.Instance.WithLargeData(),
56+
MyContextLargeBuffer.Default.ListMyDtoLarge);
57+
}
58+
59+
[Benchmark]
60+
public async Task MyDtoLargeNoSG()
61+
{
62+
await JsonSerializer.SerializeAsync(Stream.Null, TestData.Instance.WithLargeData(), _optionsBuffer);
63+
}
64+
65+
#endregion
66+
67+
}
68+
69+
public class TestData
70+
{
71+
72+
#region Constants & Statics
73+
74+
public static TestData Instance { get; } = new TestData();
75+
76+
#endregion
77+
78+
private readonly List<MyDtoLarge> _withLargeData;
79+
private readonly List<MyDto> _withPlainData;
80+
private readonly MyDto _withPlain;
81+
private readonly MyDtoLarge _withLarge;
82+
83+
private TestData()
84+
{
85+
_withPlain = new MyDto();
86+
for (var i = 0; i < 7; i++)
87+
{
88+
_withPlain.Text
89+
.Add(
90+
"The DevOps engineer deployed containerized microservices to a Kubernetes while monitoring system metrics carefully.");
91+
}
92+
93+
_withLarge = new MyDtoLarge();
94+
for (var i = 0; i < 4; i++)
95+
{
96+
_withLarge.Text
97+
.Add(
98+
"A software developer implemented error robust handling in the API gateway to ensure reliable microservice");
99+
}
100+
101+
_withPlainData = [];
102+
for (var i = 0; i < 1000; i++)
103+
{
104+
var current = new MyDto();
105+
for (var j = 0; j < 7; j++)
106+
{
107+
current.Text
108+
.Add(
109+
"The DevOps engineer deployed containerized microservices to a Kubernetes while monitoring system metrics carefully.");
110+
}
111+
112+
_withPlainData.Add(current);
113+
}
114+
115+
_withLargeData = [];
116+
for (var i = 0; i < 1000; i++)
117+
{
118+
var current = new MyDtoLarge();
119+
for (var j = 0; j < 4; j++)
120+
{
121+
current.Text
122+
.Add(
123+
"A software developer implemented error robust handling in the API gateway to ensure reliable microservice");
124+
}
125+
126+
_withLargeData.Add(current);
127+
}
128+
}
129+
130+
#region Methods
131+
132+
public MyDto WithPlain()
133+
{
134+
return _withPlain;
135+
}
136+
137+
public MyDtoLarge WithLarge()
138+
{
139+
return _withLarge;
140+
}
141+
142+
public List<MyDtoLarge> WithLargeData()
143+
{
144+
return _withLargeData;
145+
}
146+
147+
public List<MyDto> WithPlainData()
148+
{
149+
return _withPlainData;
150+
}
151+
152+
#endregion
153+
154+
}
155+
156+
public class MyDto
157+
{
158+
159+
#region Properties
160+
161+
public string Description { get; set; } = "hello";
162+
163+
public List<string> Text { get; set; } = [];
164+
165+
#endregion
166+
167+
}
168+
169+
public class MyDtoLarge
170+
{
171+
172+
#region Properties
173+
174+
public string Description { get; set; } = "hello";
175+
176+
public string Description1 { get; set; } = "hello";
177+
178+
public string Description2 { get; set; } = "hello";
179+
180+
public string Description3 { get; set; } = "hello";
181+
182+
public string Name { get; set; } = "binarytree";
183+
184+
public string Name1 { get; set; } = "binarytree";
185+
186+
public string Name2 { get; set; } = "binarytree";
187+
188+
public string Name3 { get; set; } = "binarytree";
189+
190+
public DateTime Now { get; set; } = DateTime.Now;
191+
192+
public DateTime Now1 { get; set; } = DateTime.Now;
193+
194+
public DateTime Now2 { get; set; } = DateTime.Now;
195+
196+
public DateTime Now3 { get; set; } = DateTime.Now;
197+
198+
public List<string> Text { get; set; } = [];
199+
200+
public List<string> Text1 { get; set; } = [];
201+
202+
public List<string> Text2 { get; set; } = [];
203+
204+
public List<string> Text3 { get; set; } = [];
205+
206+
public bool What { get; set; } = true;
207+
208+
public bool What1 { get; set; } = true;
209+
210+
public bool What2 { get; set; } = true;
211+
212+
public bool What3 { get; set; } = true;
213+
214+
#endregion
215+
216+
public double PreciseValue = Random.Shared.NextDouble();
217+
public double PreciseValue1 = Random.Shared.NextDouble();
218+
public double PreciseValue2 = Random.Shared.NextDouble();
219+
public double PreciseValue3 = Random.Shared.NextDouble();
220+
}
221+
222+
[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
223+
[JsonSerializable(typeof(MyDto))]
224+
[JsonSerializable(typeof(MyDtoLarge))]
225+
[JsonSerializable(typeof(List<MyDtoLarge>))]
226+
[JsonSerializable(typeof(List<MyDto>))]
227+
public partial class MyContext : JsonSerializerContext
228+
{
229+
}
230+
231+
[JsonSourceGenerationOptions(
232+
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
233+
DefaultBufferSize = 2 * 1024 * 1024)]
234+
[JsonSerializable(typeof(MyDto))]
235+
[JsonSerializable(typeof(MyDtoLarge))]
236+
[JsonSerializable(typeof(List<MyDtoLarge>))]
237+
[JsonSerializable(typeof(List<MyDto>))]
238+
public partial class MyContextLargeBuffer : JsonSerializerContext
239+
{
240+
}

src/plugins/NewtonsoftJsonTest/SystemTextJsonTestGeneratorTest.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ public static void SerializeTest()
5050
{
5151
var data = new WeatherForecast { Data = "Sunny", DataList = [true, 1] };
5252

53+
JsonSerializer.Serialize(Stream.Null, data, WeatherForecastContext.Default.WeatherForecast);
54+
5355
var jsonString = JsonSerializer.Serialize(data, WeatherForecastContext.Default.WeatherForecast);
5456
//output:
5557
//{

0 commit comments

Comments
 (0)