Я тестировал сериализацию protobuf, и кажется, что для меньшего количества объектов она медленнее, чем обычная сериализация контрактов данных. Размер передачи больше при использовании 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; }
}
вот мои методы для служб WCF с protobuf (то же самое для контракта данных без ms)
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 элементов) Время приема (Datacontract Serialization): 2200 мс (10000 элементов)
Я тестирую его на 20000 объектах. Он дал мне первый звонок.
Время для приема (Protobuf): 11258 мс (20000 элементов) Время для десериализации (Protobuf): 133 мс (20000 элементов) Время для приема (Datacontract Serialization): 3726 мс (20000 элементов)
на второй звонок
Время для приема (Protobuf): 2844 мс (20000 элементов) Время для десериализации (Protobuf): 141 мс (20000 элементов) Время для приема (Datacontract Serialization): 7541 мс (20000 элементов)
для третьего
Время для приема (Protobuf): 2767 мс (20000 элементов) Время для десериализации (Protobuf): 145 мс (20000 элементов) Время для приема (Datacontract Serialization): 3989 мс (20000 элементов)
После активации MTOM на «Protobuf transfert» мне выдали:
для первого звонка
Время для приема (Protobuf): 3316 мс (20000 элементов) Время для десериализации (Protobuf): 63 мс (20000 элементов) Время для приема (Datacontract Serialization): 3769 мс (20000 элементов)
для второго звонка
Время для приема (Protobuf): 2279 мс (20000 элементов) Время для десериализации (Protobuf): 57 мс (20000 элементов) Время для приема (Datacontract Serialization): 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 с protobuf и 1038236 с DataContractSerializer. Продолжительность вызова лучше и стабильнее этим утром. первый вызов protobuf = 2498 мс. datacontract = 5085 мс.
второй вызов protobuf = 3649 мс, дата контракта = 3840 мс
третий вызов protobuf = 2498 мс, дата контракта = 5085 мс
Serializer.PrepareSerializer<Titi>()
где-нибудь во время запуска приложения, если хотите минимизировать любые отложенные затраты. - person Marc Gravell   schedule 26.04.2011