[英]Just serialise to byte[] Protobuf
我正在尝试编写一个基准测试,将 JSON 序列化与 Protobuf 序列化速度进行比较,以用于我明天要做的演示。
using System.Text;
using System.Text.Json;
using AutoFixture;
using BenchmarkDotNet.Attributes;
using ProtobufDemo.ProtoModels;
using Google.Protobuf;
namespace Benchmark;
public class JsonVsProtoBenchmark
{
private readonly AddressBook _addressBook;
public JsonVsProtoBenchmark()
{
Fixture fixture = new();
_addressBook = fixture.Create<AddressBook>();
}
[Benchmark]
public void SerialiseToJsonOnly() => JsonSerializer.Serialize(_addressBook);
[Benchmark]
public void SerialiseToJsonEncodeAndWrite() // This is more representative of what the protobuf serialiser is actually doing
{
string json = JsonSerializer.Serialize(_addressBook);
byte[] encodedBytes = Encoding.UTF8.GetBytes(json);
Stream.Null.Write(encodedBytes);
Stream.Null.Flush();
}
[Benchmark]
public void SerialiseToProtobufAndWrite() => _addressBook.WriteTo(Stream.Null); // Note we have an extra write here that's not necessarily fair
}
然而,这远非一个公平的测试,因为IMessage.WriteTo(Stream)
所做的远不止序列化。 即使是第一层也会加载:
public static void WriteTo(this IMessage message, Stream output)
{
ProtoPreconditions.CheckNotNull(message, "message");
ProtoPreconditions.CheckNotNull(output, "output");
CodedOutputStream codedOutput = new CodedOutputStream(output);
message.WriteTo(codedOutput);
codedOutput.Flush();
}
我试图通过我的SerialiseToJsonEncodeAndWrite()
测试来弥补其中的一部分,但即便如此,它也不是真正的同类比较。
有什么办法可以只执行序列化步骤而不是通过.WriteTo()
。
事实证明,我可以避免使用接受Stream
的扩展方法,而是直接使用.WriteTo(CodedOutputStream)
方法,这几乎消除了所有这些开销。 如果我在我的基准设置中预先创建它以及一个 NullStream 实例,我会得到更具代表性的测试。
public class JsonVsProtoBenchmark
{
private AddressBook _addressBook = null!;
private CodedOutputStream _codedOutputStream = null!;
private Stream _nullStream = null!;
[GlobalSetup]
public void Setup()
{
Fixture fixture = new();
_addressBook = fixture.Create<AddressBook>();
_codedOutputStream = new(Stream.Null);
_nullStream = Stream.Null;
}
[Benchmark]
public void SerialiseToSystemTextJsonOnly() => JsonSerializer.Serialize(_addressBook);
[Benchmark]
public void SerialiseToJsonEncodeAndWrite() // This is more representative of what the protobuf serialiser is actually doing
{
string json = JsonSerializer.Serialize(_addressBook);
byte[] encodedBytes = Encoding.UTF8.GetBytes(json);
_nullStream.Write(encodedBytes);
_nullStream.Flush();
}
[Benchmark]
public void SerialiseToProtobufAndWrite() => _addressBook.WriteTo(_codedOutputStream); // Note we have an extra write here that's not necessarily fair
}
这显然还有一些问题,但它似乎比使用扩展方法时更接近。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.