gpt4 book ai didi

c# - WCF 上 protobuf-net 与 DataContractSerializer 的性能对比

转载 作者:太空狗 更新时间:2023-10-30 01:09:56 29 4
gpt4 key购买 nike

我测试了 protobuf 序列化,似乎对于低于一定数量的对象,它比常规数据契约(Contract)序列化慢。使用 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 的数据契约(Contract)也是如此)

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;
}
}

数据契约服务

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 毫秒(10000 个元素)反序列化时间 (Protobuf):138 毫秒(10000 个元素)接收时间(数据契约(Contract)序列化):2200 毫秒(10000 个元素)

我用 20000 个对象测试它它给了我第一个电话

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

第二次调用

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

第三个

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

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

第一次通话

接收时间 (Protobuf):3316 毫秒(20000 个元素)反序列化时间 (Protobuf):63 毫秒(20000 个元素)接收时间(数据契约(Contract)序列化):3769 毫秒(20000 个元素)

第二次调用

接收时间 (Protobuf):2279 毫秒(20000 个元素)反序列化时间 (Protobuf):57 毫秒(20000 个元素)接收时间(数据契约(Contract)序列化):3959 毫秒(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 with protobuf 和 1038236 with DataContractSerializer今天早上的通话时间更好更稳定第一次打电话protobuf = 2498 毫秒数据契约(Contract) = 5085 毫秒

第二次通话protobuf = 3649 毫秒数据契约(Contract) = 3840 毫秒

第三次通话protobuf = 2498 毫秒数据契约(Contract) = 5085 毫秒

最佳答案

一些影响性能的因素:

  • 序列化器准备好了吗?这在每种类型的第一次使用时是自动的;第一次通过时,它需要进行大量检查等以弄清楚您的模型是如何工作的。您可以通过调用 Serializer.PrepareSerializer<YourType>() 来抵消它启动期间的某个地方
    • 或者作为替代方案,在 v2(作为“alpha”提供)中,如果您需要尽可能快的冷启动性能,您可以将序列化程序预先生成为 dll
  • 交通工具是什么?特别是对于 WCF,你需要记住你的 byte[]已编码(当然,这在套接字上不是问题);例如,传输可以使用 MTOM 吗?还是 base-64 编码 byte[]
    • 还要注意 Stream 是可能的和 byte[]处理方式不同;如果你可以测量带宽,你可能想尝试两者
    • 如果您的目标是绝对速度,则启用 MTOM 的 basic-http 是我对 WCF 传输的偏好;或套接字,如果你想接近极限

关于c# - WCF 上 protobuf-net 与 DataContractSerializer 的性能对比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5787844/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com