簡體   English   中英

protobuf-net與DataContractSerializer在WCF上的性能

[英]Performance of protobuf-net vs DataContractSerializer over WCF

我測試了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 ms(20000個元素)接收時間(Datacontract Serialization):7541 ms(20000個元素)

第三個

接收時間(Protobuf):2767ms(20000個元素)反序列化時間(Protobuf):145 ms(20000個元素)接收時間(Datacontract Serialization):3989 ms(20000個元素)

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

第一次打電話

接收時間(Protobuf):3316 ms(20000個元素)反序列化時間(Protobuf):63 ms(20000個元素)接收時間(Datacontract Serialization):3769 ms(20000個元素)

第二次通話

接收時間(Protobuf):2279 ms(20000個元素)反序列化的時間(Protobuf):57 ms(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();

它給了我帶有protobuf的637780和帶有DataContractSerializer的1038236呼叫的持續時間更好更穩定今天早上第一次調用protobuf = 2498 ms datacontract = 5085 ms

第二次調用protobuf = 3649 ms datacontract = 3840 ms

第三次調用protobuf = 2498 ms datacontract = 5085 ms

影響績效的一些因素:

  • 是序列化器准備好了嗎 這是第一次使用每種類型時自動進行的; 第一次,它需要做相當多的檢查等,以弄清楚你的模型是如何工作的。 你可以通過在啟動期間的某個地方調用Serializer.PrepareSerializer<YourType>()來抵消這一點
    • 或者作為替代,在v2(可用作“alpha”)中,如果您需要盡可能快的冷啟動性能,您可以將序列化程序預生成為dll
  • 什么是運輸? 特別是對於WCF,你需要記住你的byte[]是如何編碼的(當然這不是套接字上的問題); 例如,運輸可以使用MTOM嗎? 或者它是base-64編碼byte[]
    • 並注意Streambyte[]的處理方式可能不同; 如果你可以測量帶寬,你可能想嘗試兩者
    • 如果絕對速度是您的目標,那么啟用MTOM的basic-http是我對WCF傳輸的偏好; 或插座,如果你想接近極限

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM