Skip to content

Commit 2031d54

Browse files
authored
Implement async serialization (#5)
Implement async serialization Add unit tests Use matrix for benchmark execution
1 parent 51003d2 commit 2031d54

50 files changed

Lines changed: 1270 additions & 1219 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/dotnet.yml

Lines changed: 10 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -55,45 +55,17 @@ jobs:
5555
run: dotnet test --no-build --verbosity normal -f net6.0
5656
- name: Test .NET 8.0
5757
run: dotnet test --no-build --verbosity normal -f net8.0
58-
59-
benchmark-windows-net48:
58+
59+
benchmark-windows:
6060

6161
runs-on: windows-latest
6262
timeout-minutes: 320 #6 hours
6363
needs: build-windows
64+
strategy:
65+
matrix:
66+
target: [net48, net6.0, net8.0]
67+
benchmarkSet: [SerializersBenchmark.AsyncBenchmarks*, SerializersBenchmark.Benchmarks*]
6468
if: ${{ github.ref == 'refs/heads/main' }}
65-
66-
steps:
67-
- uses: actions/checkout@v4
68-
- name: Setup .NET 6
69-
uses: actions/setup-dotnet@v4
70-
with:
71-
dotnet-version: 6.0.x
72-
- name: Setup .NET 8
73-
uses: actions/setup-dotnet@v4
74-
with:
75-
dotnet-version: 8.0.x
76-
- name: Restore dependencies
77-
run: dotnet restore
78-
- name: Build
79-
run: dotnet build --no-restore
80-
- name: Execute .NET Framework 4.8
81-
working-directory: ./SerializersBenchmark
82-
run: dotnet run -c Release -f net48 -- --runtimes net48 --filter *
83-
- name: Publish Results
84-
uses: actions/upload-artifact@v4
85-
with:
86-
name: net48
87-
path: ./SerializersBenchmark/BenchmarkDotNet.Artifacts/results
88-
compression-level: 9
89-
90-
benchmark-windows-net6:
91-
92-
runs-on: windows-latest
93-
timeout-minutes: 320 #6 hours
94-
needs: build-windows
95-
if: ${{ github.ref == 'refs/heads/main' }}
96-
9769
steps:
9870
- uses: actions/checkout@v4
9971
- name: Setup .NET 6
@@ -107,75 +79,15 @@ jobs:
10779
- name: Restore dependencies
10880
run: dotnet restore
10981
- name: Build
110-
run: dotnet build --no-restore
111-
- name: Execute .NET 6
82+
run: dotnet build --no-restore -f ${{matrix.target}}
83+
- name: Execute
11284
working-directory: ./SerializersBenchmark
113-
run: dotnet run -c Release -f net6.0 -- --runtimes net6.0 --filter *
85+
run: dotnet run -c Release -f ${{matrix.target}} -- --job default --runtimes ${{matrix.target}} --filter ${{matrix.benchmarkSet}}
11486
- name: Publish Results
11587
uses: actions/upload-artifact@v4
11688
with:
117-
name: net6
89+
name: ${{matrix.target}}${{ matrix.benchmarkSet == 'SerializersBenchmark.AsyncBenchmarks*' && '-async' || '' }}
11890
path: ./SerializersBenchmark/BenchmarkDotNet.Artifacts/results
11991
compression-level: 9
120-
121-
benchmark-windows-net8:
122-
123-
runs-on: windows-latest
124-
timeout-minutes: 360 #6 hours
125-
needs: build-windows
126-
if: ${{ github.ref == 'refs/heads/main' }}
127-
128-
steps:
129-
- uses: actions/checkout@v4
130-
- name: Setup .NET 6
131-
uses: actions/setup-dotnet@v4
132-
with:
133-
dotnet-version: 6.0.x
134-
- name: Setup .NET 8
135-
uses: actions/setup-dotnet@v4
136-
with:
137-
dotnet-version: 8.0.x
138-
- name: Restore dependencies
139-
run: dotnet restore
140-
- name: Build
141-
run: dotnet build --no-restore
142-
- name: Execute .NET 8
143-
working-directory: ./SerializersBenchmark
144-
run: dotnet run -c Release -f net8.0 -- --runtimes net8.0 --filter *
145-
- name: Publish Results
146-
uses: actions/upload-artifact@v4
147-
with:
148-
name: net8
149-
path: ./SerializersBenchmark/BenchmarkDotNet.Artifacts/results
150-
compression-level: 9
151-
152-
#TODO process results
15392

154-
# benchmark-linux:
155-
#
156-
# runs-on: ubuntu-latest
157-
# timeout-minutes: 360
158-
# needs: build-linux
159-
# if: ${{ github.ref == 'refs/heads/main' }}
160-
#
161-
# steps:
162-
# - uses: actions/checkout@v4
163-
# - name: Setup .NET 6
164-
# uses: actions/setup-dotnet@v4
165-
# with:
166-
# dotnet-version: 6.0.x
167-
# - name: Setup .NET 8
168-
# uses: actions/setup-dotnet@v4
169-
# with:
170-
# dotnet-version: 8.0.x
171-
# - name: Restore dependencies
172-
# run: dotnet restore
173-
# - name: Build .NET 6.0
174-
# run: dotnet build --no-restore -f net6.0
175-
# - name: Build .NET 8.0
176-
# run: dotnet build --no-restore -f net8.0
177-
# - name: Execute
178-
# working-directory: ./SerializersBenchmark
179-
# run: dotnet run -c Release -f net8.0 -- --runtimes net6.0 net8.0 --filter *
180-
18193
#TODO process results

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,4 @@ Implemented benchmarks for the following serializers:
2727
- UTF8Json (https://github.com/neuecc/Utf8Json)
2828

2929
#### Legacy Serializers
30-
- ZeroFormatter
3130
- BinaryFormatter
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
using SerializersBenchmark;
2+
using SerializersBenchmark.Models;
3+
using SerializersBenchmark.Serializers;
4+
using Xunit;
5+
6+
namespace SerializerBenchmarks.UnitTests;
7+
8+
public sealed class AsyncBenchmarkTests : IDisposable
9+
{
10+
private static int _portNumber = 27003;
11+
private static int GetNextPort()
12+
{
13+
Interlocked.Increment(ref _portNumber);
14+
return _portNumber;
15+
}
16+
17+
private readonly AsyncBenchmarks _benchmark = new()
18+
{
19+
N = 1,
20+
QueueLength = 7,
21+
BlackHolePort = GetNextPort(),
22+
WhiteHolePort = GetNextPort()
23+
};
24+
25+
[Theory(Timeout = 1000)]
26+
[InlineData(typeof(Ceras<DataItem>))]
27+
[InlineData(typeof(Utf8JsonSerializer<DataItem>))]
28+
[InlineData(typeof(MessagePack<DataItem>))]
29+
[InlineData(typeof(GroBuf<DataItem>))]
30+
[InlineData(typeof(Bois<DataItem>))]
31+
[InlineData(typeof(BoisLz4<DataItem>))]
32+
[InlineData(typeof(Jil<DataItem>))]
33+
[InlineData(typeof(ProtobufNet<DataItem>))]
34+
[InlineData(typeof(GoogleProtobuf<ProtobufDataItem>))]
35+
[InlineData(typeof(ServiceStack<DataItem>))]
36+
[InlineData(typeof(FastJson<DataItem>))]
37+
[InlineData(typeof(DataContractBinaryXml<DataItem>))]
38+
[InlineData(typeof(DataContract<DataItem>))]
39+
[InlineData(typeof(XmlSerializer<DataItem>))]
40+
[InlineData(typeof(NewtonsoftJson<DataItem>))]
41+
[InlineData(typeof(MsgPackCli<DataItem>))]
42+
[InlineData(typeof(SystemTextJson<DataItem>))]
43+
#if (NET6_0_OR_GREATER)
44+
[InlineData(typeof(MemoryPack<DataItem>))]
45+
[InlineData(typeof(BinaryPack<DataItem>))]
46+
[InlineData(typeof(SpanJson<DataItem>))]
47+
[InlineData(typeof(SystemTextJsonSourceGen<DataItem>))]
48+
#endif
49+
#if NET48
50+
[InlineData(typeof(BinaryFormatter<DataItem>))]
51+
#endif
52+
public async Task SerializeAsyncTest(Type serializerType)
53+
{
54+
_benchmark.SerializerType = serializerType;
55+
await _benchmark.SetupAsync();
56+
await _benchmark.SerializeAsync();
57+
}
58+
59+
[Theory(Timeout = 1000)]
60+
[InlineData(typeof(Ceras<DataItem>))]
61+
[InlineData(typeof(Utf8JsonSerializer<DataItem>))]
62+
[InlineData(typeof(MessagePack<DataItem>))]
63+
[InlineData(typeof(GroBuf<DataItem>))]
64+
[InlineData(typeof(Bois<DataItem>))]
65+
[InlineData(typeof(BoisLz4<DataItem>))]
66+
[InlineData(typeof(Jil<DataItem>))]
67+
[InlineData(typeof(ProtobufNet<DataItem>))]
68+
[InlineData(typeof(GoogleProtobuf<ProtobufDataItem>))]
69+
[InlineData(typeof(ServiceStack<DataItem>))]
70+
[InlineData(typeof(FastJson<DataItem>))]
71+
[InlineData(typeof(DataContractBinaryXml<DataItem>))]
72+
[InlineData(typeof(DataContract<DataItem>))]
73+
[InlineData(typeof(XmlSerializer<DataItem>))]
74+
[InlineData(typeof(NewtonsoftJson<DataItem>))]
75+
[InlineData(typeof(MsgPackCli<DataItem>))]
76+
[InlineData(typeof(SystemTextJson<DataItem>))]
77+
#if (NET6_0_OR_GREATER)
78+
[InlineData(typeof(MemoryPack<DataItem>))]
79+
[InlineData(typeof(BinaryPack<DataItem>))]
80+
[InlineData(typeof(SpanJson<DataItem>))]
81+
[InlineData(typeof(SystemTextJsonSourceGen<DataItem>))]
82+
#endif
83+
#if NET48
84+
[InlineData(typeof(BinaryFormatter<DataItem>))]
85+
#endif
86+
public async Task BufferedSerializeAsyncTest(Type serializerType)
87+
{
88+
_benchmark.SerializerType = serializerType;
89+
_benchmark.UseBuffer = true;
90+
await _benchmark.SetupAsync();
91+
await _benchmark.SerializeAsync();
92+
}
93+
94+
[Theory(Timeout = 1000)]
95+
[InlineData(typeof(Ceras<DataItem>))]
96+
[InlineData(typeof(Utf8JsonSerializer<DataItem>))]
97+
[InlineData(typeof(MessagePack<DataItem>))]
98+
[InlineData(typeof(GroBuf<DataItem>))]
99+
[InlineData(typeof(Bois<DataItem>))]
100+
[InlineData(typeof(BoisLz4<DataItem>))]
101+
[InlineData(typeof(Jil<DataItem>))]
102+
[InlineData(typeof(ProtobufNet<DataItem>))]
103+
[InlineData(typeof(GoogleProtobuf<ProtobufDataItem>))]
104+
[InlineData(typeof(ServiceStack<DataItem>))]
105+
[InlineData(typeof(FastJson<DataItem>))]
106+
[InlineData(typeof(DataContractBinaryXml<DataItem>))]
107+
[InlineData(typeof(DataContract<DataItem>))]
108+
[InlineData(typeof(XmlSerializer<DataItem>))]
109+
[InlineData(typeof(NewtonsoftJson<DataItem>))]
110+
[InlineData(typeof(MsgPackCli<DataItem>))]
111+
[InlineData(typeof(SystemTextJson<DataItem>))]
112+
#if (NET6_0_OR_GREATER)
113+
[InlineData(typeof(MemoryPack<DataItem>))]
114+
[InlineData(typeof(BinaryPack<DataItem>))]
115+
[InlineData(typeof(SpanJson<DataItem>))]
116+
[InlineData(typeof(SystemTextJsonSourceGen<DataItem>))]
117+
#endif
118+
#if NET48
119+
[InlineData(typeof(BinaryFormatter<DataItem>))]
120+
#endif
121+
public async Task DeserializeAsyncTest(Type serializerType)
122+
{
123+
_benchmark.SerializerType = serializerType;
124+
await _benchmark.SetupAsync();
125+
await _benchmark.DeserializeAsync();
126+
}
127+
128+
[Theory(Timeout = 1000)]
129+
[InlineData(typeof(Ceras<DataItem>))]
130+
[InlineData(typeof(Utf8JsonSerializer<DataItem>))]
131+
[InlineData(typeof(MessagePack<DataItem>))]
132+
[InlineData(typeof(GroBuf<DataItem>))]
133+
[InlineData(typeof(Bois<DataItem>))]
134+
[InlineData(typeof(BoisLz4<DataItem>))]
135+
[InlineData(typeof(Jil<DataItem>))]
136+
[InlineData(typeof(ProtobufNet<DataItem>))]
137+
[InlineData(typeof(GoogleProtobuf<ProtobufDataItem>))]
138+
[InlineData(typeof(ServiceStack<DataItem>))]
139+
[InlineData(typeof(FastJson<DataItem>))]
140+
[InlineData(typeof(DataContractBinaryXml<DataItem>))]
141+
[InlineData(typeof(DataContract<DataItem>))]
142+
[InlineData(typeof(XmlSerializer<DataItem>))]
143+
[InlineData(typeof(NewtonsoftJson<DataItem>))]
144+
[InlineData(typeof(MsgPackCli<DataItem>))]
145+
[InlineData(typeof(SystemTextJson<DataItem>))]
146+
#if (NET6_0_OR_GREATER)
147+
[InlineData(typeof(MemoryPack<DataItem>))]
148+
[InlineData(typeof(BinaryPack<DataItem>))]
149+
[InlineData(typeof(SpanJson<DataItem>))]
150+
[InlineData(typeof(SystemTextJsonSourceGen<DataItem>))]
151+
#endif
152+
#if NET48
153+
[InlineData(typeof(BinaryFormatter<DataItem>))]
154+
#endif
155+
public async Task BufferedDeserializeAsyncTest(Type serializerType)
156+
{
157+
_benchmark.SerializerType = serializerType;
158+
_benchmark.UseBuffer = true;
159+
await _benchmark.SetupAsync();
160+
await _benchmark.DeserializeAsync();
161+
}
162+
163+
public void Dispose()
164+
{
165+
_benchmark.Cleanup();
166+
}
167+
}

0 commit comments

Comments
 (0)