编程语言
首页 > 编程语言> > c# – 通过WCF实现protobuf-net与DataContractSerializer的性能

c# – 通过WCF实现protobuf-net与DataContractSerializer的性能

作者:互联网

我测试了protobuf序列化,似乎对于一定数量的对象,它比常规的datacontract序列化慢.使用DataContractSerializer传输大小更大但在序列化和反序列化期间使用DataContractSerializer更快

你认为这是正常的还是我犯了错误?

[DataContract]
public partial class Toto
{
    [DataMember]
    public string NomToto { get; set; }

    [DataMember]
    public string PrenomToto { get; set; }
} 

这是我的datacontract课程,这与protobuf相同

[ProtoContract]
public partial class Titi
{
    [ProtoMember(1)]
    public string NomTiti { get; set; }

    [ProtoMember(2)]
    public string PrenomTiti { get; set; }
}

这是我使用protobuf进行WCF服务的方法(对于没有ms的datacontract,相同)

public class TitiService : ITitiService
{
    public byte[] GetAllTitis()
    {
        List<Titi> titiList = new List<Titi>();
        for (int i = 0; i < 20000; i++)
        {
            var titi = new Titi
            {
                NomTiti = "NomTiti" + i,
                PrenomTiti = "PrenomTiti" + i
            };
            titiList.Add(titi);
        }
        var ms = new MemoryStream();
        Serializer.Serialize(ms, titiList);

        byte[] arr = ms.ToArray();
        return arr;
    }
}

具有datacontract的服务

public class TotoService : ITotoService
{
    public List<Toto> GetAllTotos()
    {
        List<Toto> totoList = new List<Toto>();
        for (int i = 0; i<20000; i++)
        {
            var toto = new Toto
            {
                NomToto = "NomToto" + i,
                PrenomToto = "PrenomToto" + i
            };
            totoList.Add(toto);
        }
        return totoList;
    }
}

这是客户电话

    public partial class Program
{
    static ProtobufTestAzure.Client.TitiService.TitiServiceClient TitiClient;
    static ProtobufTestAzure.Client.TotoService.TotoServiceClient TotoClient;

    public static void Main(string[] args)
    {
        Stopwatch stopwatch1 = new Stopwatch();
        Stopwatch stopwatch2 = new Stopwatch();
        Stopwatch stopwatch3 = new Stopwatch();

        stopwatch1.Start();

        TitiClient = new ProtobufTestAzure.Client.TitiService.TitiServiceClient();
        Byte[] titiByte = TitiClient.GetAllTitis();
        TitiClient.Close();

        stopwatch1.Stop();


        stopwatch2.Start();

        var ms = new MemoryStream(titiByte);
        List<Titi> TitiList = Serializer.Deserialize<List<Titi>>(ms);

        stopwatch2.Stop();

        Console.WriteLine(" ");

        stopwatch3.Start();

        TotoClient = new ProtobufTestAzure.Client.TotoService.TotoServiceClient();
        var TotoList = TotoClient.GetAllTotos();
        TotoClient.Close();

        stopwatch3.Stop();

        Console.WriteLine("Time elapse for reception (Protobuf): {0} ms ({1} éléments)", stopwatch1.ElapsedMilliseconds, TitiList.Count);
        Console.WriteLine("Time elapse for deserialization (Protobuf : {0} ms ({1} éléments)", stopwatch2.ElapsedMilliseconds, TitiList.Count);
        Console.WriteLine("Time elapse for réception (Datacontract Serialization) : {0} ms ({1} éléments)", stopwatch3.ElapsedMilliseconds, TotoList.Count);

        Console.ReadLine();
    }
}

和10000个对象的结果

接收时间(Protobuf):3359 ms(10000个元素)
反序列化的时间(Protobuf):138 ms(10000个元素)
接收时间(Datacontract Serialization):2200ms(10000个元素)

我用20000个物体测试它
它给了我第一个电话

接收时间(Protobuf):11258ms(20000个元素)
反序列化的时间(Protobuf):133ms(20000个元素)
接收时间(Datacontract Serialization):3726ms(20000个元素)

第二次通话

接收时间(Protobuf):2844 ms(20000个元素)
反序列化的时间(Protobuf):141毫秒(20000个元素)
接收时间(Datacontract Serialization):7541 ms(20000个元素)

第三个

接收时间(Protobuf):2767ms(20000个元素)
反序列化的时间(Protobuf):145毫秒(20000个元素)
接收时间(Datacontract Serialization):3989 ms(20000个元素)

在“Protobuf transfert”上激活MTOM后,它给了我:

第一次打电话

接收时间(Protobuf):3316 ms(20000个元素)
反序列化的时间(Protobuf):63毫秒(20000个元素)
接收时间(Datacontract Serialization):3769 ms(20000个元素)

第二次通话

接收时间(Protobuf):2279 ms(20000个元素)
反序列化的时间(Protobuf):57毫秒(20000个元素)
接收时间(Datacontract Serialization):3959 ms(20000个元素)

我为对象大小添加了这部分代码

            long totoSize = new long();
        using (Stream s = new MemoryStream())
        {
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(s, totoList);
            totoSize = s.Length;
        }

        long titiSize = titiByte.Count();

它给了我637780的protobuf和1038236的DataContractSerializer
今天早上呼叫的持续时间更好,更稳定
第一次打电话
protobuf = 2498 ms
datacontract = 5085 ms

第二个电话
protobuf = 3649毫秒
datacontract = 3840毫秒

第三个电话
protobuf = 2498 ms
datacontract = 5085 ms

解决方法:

影响绩效的一些因素:

>是序列化器准备好了吗?这是第一次使用每种类型时自动进行的;第一次,它需要做相当多的检查等,以弄清楚你的模型是如何工作的.您可以通过在启动期间的某处调用Serializer.PrepareSerializer< YourType>()来抵消这一点

>或者作为替代,在v2(可用作“alpha”)中,如果您需要尽可能快的冷启动性能,您可以将序列化器预生成为dll

>什么是运输?特别是对于WCF,你需要记住你的byte []是如何编码的(当然这不是套接字上的问题);例如,运输可以使用MTOM吗?或者它是base-64编码byte []?

>并注意Stream和byte []的处理方式可能不同;如果你可以测量带宽,你可能想尝试两者
>如果绝对速度是您的目标,那么启用MTOM的basic-http是我对WCF传输的偏好;或插座,如果你想接近极限

标签:c,protobuf-net,datacontractserializer
来源: https://codeday.me/bug/20190621/1255059.html