繁体   English   中英

只需序列化为 byte[] Protobuf

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM