Created
September 15, 2022 20:06
-
-
Save neuecc/c19bdca5434bf60751dfd02a1529e62f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//<Project Sdk="Microsoft.NET.Sdk"> | |
// <PropertyGroup> | |
// <OutputType>Exe</OutputType> | |
// <TargetFramework>net6.0</TargetFramework> | |
// <ImplicitUsings>enable</ImplicitUsings> | |
// <Nullable>enable</Nullable> | |
// </PropertyGroup> | |
// <ItemGroup> | |
// <PackageReference Include="BenchmarkDotNet" Version="0.13.2" /> | |
// <PackageReference Include="MessagePack" Version="2.4.35" /> | |
// <PackageReference Include="protobuf-net" Version="3.1.17" /> | |
// <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" /> | |
// <PackageReference Include="Microsoft.Orleans.CodeGenerator" Version="4.0.0-preview2"> | |
// <PrivateAssets>all</PrivateAssets> | |
// <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | |
// </PackageReference> | |
// <PackageReference Include="Microsoft.Orleans.Serialization" Version="4.0.0-preview2" /> | |
// </ItemGroup> | |
//</Project> | |
/* | |
BenchmarkDotNet=v0.13.2, OS=Windows 10 (10.0.19044.2006/21H2/November2021Update) | |
AMD Ryzen 9 5950X, 1 CPU, 32 logical and 16 physical cores | |
.NET SDK=7.0.100-rc.1.22431.12 | |
[Host] : .NET 6.0.9 (6.0.922.41905), X64 RyuJIT AVX2 | |
Job-TTHSYX : .NET 6.0.9 (6.0.922.41905), X64 RyuJIT AVX2 | |
IterationCount=1 WarmupCount=1 | |
| Method | Categories | Mean | Error | Ratio | Gen0 | Gen1 | Allocated | Alloc Ratio | | |
|--------------------------- |------------- |---------:|------:|------:|-------:|-------:|----------:|------------:| | |
| MessagePackSerialize | byte[] | 11.06 us | NA | 1.00 | 0.9460 | 0.0458 | 16032 B | 1.00 | | |
| ProtobufNetSerialize | byte[] | 40.88 us | NA | 3.70 | 0.9766 | 0.0610 | 17025 B | 1.06 | | |
| SystemTextJsonSerialize | byte[] | 51.69 us | NA | 4.67 | 2.9297 | 0.1221 | 49521 B | 3.09 | | |
| OrleansSerialize | byte[] | 34.15 us | NA | 3.09 | 6.7139 | 0.3662 | 113032 B | 7.05 | | |
| | | | | | | | | | | |
| MessagePackBufferWriter | BufferWriter | 10.86 us | NA | 1.00 | - | - | - | NA | | |
| ProtobufNetBufferWriter | BufferWriter | 53.34 us | NA | 4.91 | - | - | - | NA | | |
| SystemTextJsonBufferWriter | BufferWriter | 56.52 us | NA | 5.20 | 1.8921 | - | 32344 B | NA | | |
| OrleansBufferWriter | BufferWriter | 33.79 us | NA | 3.11 | 5.7373 | - | 96000 B | NA | | |
| OrleansBufferWriter2 | BufferWriter | 54.26 us | NA | 5.00 | 5.7373 | - | 96000 B | NA | | |
*/ | |
using BenchmarkDotNet.Attributes; | |
using BenchmarkDotNet.Columns; | |
using BenchmarkDotNet.Configs; | |
using BenchmarkDotNet.Diagnosers; | |
using BenchmarkDotNet.Exporters; | |
using BenchmarkDotNet.Jobs; | |
using BenchmarkDotNet.Running; | |
using MessagePack; | |
using Microsoft.Extensions.DependencyInjection; | |
using Orleans; | |
using Orleans.Serialization; | |
using Orleans.Serialization.Buffers; | |
using Orleans.Serialization.Session; | |
using ProtoBuf; | |
using System.Buffers; | |
using System.Text; | |
using System.Text.Json; | |
var config = ManualConfig.CreateMinimumViable() | |
.AddDiagnoser(MemoryDiagnoser.Default) | |
.AddExporter(DefaultExporters.Plain) | |
.AddJob(Job.Default.WithWarmupCount(1).WithIterationCount(1)); | |
BenchmarkRunner.Run<SerializeTest<Vector3[]>>(config, args); | |
[MessagePackObject] | |
[ProtoContract] | |
[GenerateSerializer] | |
public struct Vector3 | |
{ | |
[Key(0)] | |
[ProtoMember(1)] | |
[Id(0)] | |
public float X; | |
[Key(1)] | |
[ProtoMember(2)] | |
[Id(1)] | |
public float Y; | |
[Key(2)] | |
[ProtoMember(3)] | |
[Id(2)] | |
public float Z; | |
} | |
[CategoriesColumn] | |
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] | |
public class SerializeTest<T> | |
{ | |
T value; | |
ArrayBufferWriter<byte> writer; | |
SerializerSessionPool pool; | |
Serializer<T> orleansSerializer; | |
MemoryStream stream; | |
Utf8JsonWriter jsonWriter; | |
public SerializeTest() | |
{ | |
if (typeof(T) == typeof(Vector3[])) | |
{ | |
value = (T)(object)Enumerable.Repeat(new Vector3 { X = 10.3f, Y = 40.5f, Z = 13411.3f }, 1000).ToArray(); | |
} | |
else | |
{ | |
throw new NotSupportedException(); | |
} | |
// Orleans | |
var serviceProvider = new ServiceCollection() | |
.AddSerializer(builder => builder.AddAssembly(typeof(SerializeTest<>).Assembly)) | |
.BuildServiceProvider(); | |
pool = serviceProvider.GetRequiredService<SerializerSessionPool>(); | |
orleansSerializer = serviceProvider.GetRequiredService<Serializer<T>>(); | |
// create buffers | |
stream = new MemoryStream(); | |
var serialize1 = orleansSerializer.SerializeToArray(value); | |
var serialize2 = MessagePackSerializer.Serialize(value); | |
ProtoBuf.Serializer.Serialize(stream, value); | |
var serialize3 = stream.ToArray(); | |
stream.Position = 0; | |
var serialize4 = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value)); | |
writer = new ArrayBufferWriter<byte>(new[] { serialize1, serialize2, serialize3, serialize4 }.Max(x => x.Length)); | |
jsonWriter = new Utf8JsonWriter(writer); | |
} | |
// return byte[] | |
[Benchmark(Baseline = true), BenchmarkCategory(" byte[]")] | |
public byte[] MessagePackSerialize() | |
{ | |
return MessagePackSerializer.Serialize(value); | |
} | |
[Benchmark, BenchmarkCategory(" byte[]")] | |
public byte[] ProtobufNetSerialize() | |
{ | |
ProtoBuf.Serializer.Serialize(stream, value); | |
var array = stream.ToArray(); | |
stream.Position = 0; | |
return array; | |
} | |
[Benchmark, BenchmarkCategory(" byte[]")] | |
public byte[] SystemTextJsonSerialize() | |
{ | |
JsonSerializer.Serialize(stream, value); | |
var array = stream.ToArray(); | |
stream.Position = 0; | |
return array; | |
} | |
[Benchmark, BenchmarkCategory(" byte[]")] | |
public byte[] OrleansSerialize() | |
{ | |
return orleansSerializer.SerializeToArray(value); | |
} | |
// use BufferWriter | |
[Benchmark(Baseline = true), BenchmarkCategory("BufferWriter")] | |
public void MessagePackBufferWriter() | |
{ | |
MessagePackSerializer.Serialize(writer, value); | |
writer.Clear(); | |
} | |
[Benchmark, BenchmarkCategory("BufferWriter")] | |
public void ProtobufNetBufferWriter() | |
{ | |
ProtoBuf.Serializer.Serialize(writer, value); | |
writer.Clear(); | |
} | |
[Benchmark, BenchmarkCategory("BufferWriter")] | |
public void SystemTextJsonBufferWriter() | |
{ | |
JsonSerializer.Serialize(jsonWriter, value); | |
jsonWriter.Flush(); | |
writer.Clear(); | |
jsonWriter.Reset(writer); | |
} | |
[Benchmark, BenchmarkCategory("BufferWriter")] | |
public void OrleansBufferWriter() | |
{ | |
using (var session = pool.GetSession()) | |
{ | |
var writer = Writer.CreatePooled(session); | |
try | |
{ | |
orleansSerializer.Serialize(value, ref writer); | |
writer.Commit(); | |
} | |
finally | |
{ | |
writer.Dispose(); | |
} | |
} | |
} | |
[Benchmark, BenchmarkCategory("BufferWriter")] | |
public void OrleansBufferWriter2() | |
{ | |
using (var session = pool.GetSession()) | |
{ | |
// wrap ArrayBufferWriter<byte> | |
var writer2 = writer.CreateWriter(session); | |
try | |
{ | |
orleansSerializer.Serialize(value, ref writer2); | |
writer2.Commit(); | |
} | |
finally | |
{ | |
writer2.Dispose(); | |
} | |
writer.Clear(); // clear ArrayBufferWriter<byte> | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment