C# 基于WCF的protobuf net与DataContractSerializer的性能比较
我测试了protobuf序列化,对于低于一定数量的对象,它似乎比常规datacontract序列化慢。使用DataContractSerializer时,传输大小更大,但在序列化和反序列化过程中,使用DataContractSerializer会更快 你认为这是正常的还是我犯了一个错误C# 基于WCF的protobuf net与DataContractSerializer的性能比较,c#,datacontractserializer,protobuf-net,C#,Datacontractserializer,Protobuf Net,我测试了protobuf序列化,对于低于一定数量的对象,它似乎比常规datacontract序列化慢。使用DataContractSerializer时,传输大小更大,但在序列化和反序列化过程中,使用DataContractSerializer会更快 你认为这是正常的还是我犯了一个错误 [DataContract] public partial class Toto { [DataMember] public string NomToto { get; set; } [
[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也一样)
它给了我637780和protobuf,1038236和DataContractSerializer
今天早上通话的持续时间更好更稳定
第一个电话
protobuf=2498毫秒
datacontract=5085毫秒
第二次呼叫
protobuf=3649毫秒
datacontract=3840毫秒
第三次呼叫
protobuf=2498毫秒
datacontract=5085毫秒影响性能的一些因素:
- 序列化程序准备好了吗?每种类型第一次使用时,这是自动的;第一次通过时,需要进行大量的检查等,以了解您的模型是如何工作的。您可以通过在启动过程中调用
来抵消这一点Serializer.PrepareSerializer()
- 或者,在v2(可用作“alpha”)中,如果需要尽可能快的冷启动性能,可以将序列化程序作为dll预生成
- 什么是交通工具?特别是对于WCF,您需要记住您的
是如何编码的(当然,这在套接字上不是问题);例如,传输可以使用MTOM吗?还是base-64编码的是字节[]
?字节[]
- 还要注意,
和流
的处理可能不同;如果您可以测量带宽,您可能想同时尝试这两种方法字节[]
- 如果绝对速度是您的目标,那么启用MTOM的基本http是我对WCF传输的首选;如果你想接近极限的话,也可以使用插座
- 还要注意,
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();
}
}
long totoSize = new long();
using (Stream s = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(s, totoList);
totoSize = s.Length;
}
long titiSize = titiByte.Count();