Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 序列化/反序列化的XML与二进制性能_C#_.net_Serialization_Compact Framework_Protobuf Net - Fatal编程技术网

C# 序列化/反序列化的XML与二进制性能

C# 序列化/反序列化的XML与二进制性能,c#,.net,serialization,compact-framework,protobuf-net,C#,.net,Serialization,Compact Framework,Protobuf Net,我正在开发一个紧凑的框架应用程序,需要提高性能。该应用程序目前通过将对象序列化为XML并将其存储在数据库中脱机工作。使用分析工具,我可以看到这是一个相当大的开销,减慢了应用程序。我认为如果我切换到二进制序列化,性能会提高,但因为紧凑型框架不支持这一点,所以我查看了protobuf net。序列化似乎更快,但反序列化要慢得多,而且应用程序的反序列化比序列化做得更多 二进制序列化应该更快吗?如果应该,我可以做些什么来提高性能?下面是我如何使用XML和二进制的一个片段: XML序列化: public

我正在开发一个紧凑的框架应用程序,需要提高性能。该应用程序目前通过将对象序列化为XML并将其存储在数据库中脱机工作。使用分析工具,我可以看到这是一个相当大的开销,减慢了应用程序。我认为如果我切换到二进制序列化,性能会提高,但因为紧凑型框架不支持这一点,所以我查看了protobuf net。序列化似乎更快,但反序列化要慢得多,而且应用程序的反序列化比序列化做得更多

二进制序列化应该更快吗?如果应该,我可以做些什么来提高性能?下面是我如何使用XML和二进制的一个片段:

XML序列化:

public string Serialize(T obj)
{
  UTF8Encoding encoding = new UTF8Encoding();
  XmlSerializer serializer = new XmlSerializer(typeof(T));
  MemoryStream stream = new MemoryStream();
  XmlTextWriter writer = new XmlTextWriter(stream, Encoding.UTF8);
  serializer.Serialize(stream, obj);
  stream = (MemoryStream)writer.BaseStream;
  return encoding.GetString(stream.ToArray(), 0, Convert.ToInt32(stream.Length));
}
public T Deserialize(string xml)
{
  UTF8Encoding encoding = new UTF8Encoding();
  XmlSerializer serializer = new XmlSerializer(typeof(T));
  MemoryStream stream = new MemoryStream(encoding.GetBytes(xml));            
  return (T)serializer.Deserialize(stream);
}
public byte[] Serialize(T obj)
{
  byte[] raw;
  using (MemoryStream memoryStream = new MemoryStream())
  {
    Serializer.Serialize(memoryStream, obj);
    raw = memoryStream.ToArray();
  }

  return raw;            
}

public T Deserialize(byte[] serializedType)
{
  T obj;
  using (MemoryStream memoryStream = new MemoryStream(serializedType))
  {
    obj = Serializer.Deserialize<T>(memoryStream);
  }
  return obj;
}
Protobuf网络二进制序列化:

public string Serialize(T obj)
{
  UTF8Encoding encoding = new UTF8Encoding();
  XmlSerializer serializer = new XmlSerializer(typeof(T));
  MemoryStream stream = new MemoryStream();
  XmlTextWriter writer = new XmlTextWriter(stream, Encoding.UTF8);
  serializer.Serialize(stream, obj);
  stream = (MemoryStream)writer.BaseStream;
  return encoding.GetString(stream.ToArray(), 0, Convert.ToInt32(stream.Length));
}
public T Deserialize(string xml)
{
  UTF8Encoding encoding = new UTF8Encoding();
  XmlSerializer serializer = new XmlSerializer(typeof(T));
  MemoryStream stream = new MemoryStream(encoding.GetBytes(xml));            
  return (T)serializer.Deserialize(stream);
}
public byte[] Serialize(T obj)
{
  byte[] raw;
  using (MemoryStream memoryStream = new MemoryStream())
  {
    Serializer.Serialize(memoryStream, obj);
    raw = memoryStream.ToArray();
  }

  return raw;            
}

public T Deserialize(byte[] serializedType)
{
  T obj;
  using (MemoryStream memoryStream = new MemoryStream(serializedType))
  {
    obj = Serializer.Deserialize<T>(memoryStream);
  }
  return obj;
}
public byte[]序列化(T obj)
{
字节[]原始;
使用(MemoryStream MemoryStream=new MemoryStream())
{
Serializer.Serialize(memoryStream,obj);
raw=memoryStream.ToArray();
}
返回原材料;
}
公共T反序列化(字节[]serializedType)
{
T-obj;
使用(MemoryStream MemoryStream=新的MemoryStream(serializedType))
{
obj=序列化程序。反序列化(memoryStream);
}
返回obj;
}

有趣。。。想法:

  • 这是什么版本的CF;2.0? 3.5? 特别是,CF 3.5具有
    Delegate.CreateDelegate
    ,它允许protobuf net访问属性的速度比CF 2.0中的can快得多
  • 是否要注释字段或属性?同样,在CF中,反射优化是有限的;在CF 3.5中,您可以使用属性获得更好的性能,就像使用字段一样,我唯一可用的选项是
    FieldInfo.SetValue
CF中还有许多其他东西根本不存在,因此它必须在一些地方做出妥协。对于过于复杂的模型,还有一个问题。修复正在进行中,但这是一个很大的变化,需要“一段时间”


有关详细信息,请参阅常规(完整).NET上比较各种格式(包括
XmlSerializer
和protobuf-NET)的一些指标。

您是否尝试过为类创建自定义序列化类?而不是使用XmlSerializer,XmlSerializer是一个通用序列化程序(它在运行时创建一组类)。有一个工具可以做这件事(sgen)。您可以在构建过程中运行它,它会生成一个自定义程序集,可以在XmlSerializer中使用


如果您有Visual Studio,则该选项在项目属性的“生成”选项卡下可用。

序列化对象或将其写入数据库是否会影响性能?由于编写它们可能会影响某种较慢的存储,因此我认为这比序列化步骤对性能的影响要大得多

请记住,Marc Gravell发布的性能度量正在测试1000000次迭代的性能


您将它们存储在什么样的数据库中?对象是在内存中序列化还是直接存储?如何将它们发送到db?这些物体有多大?当一个对象被更新时,是将所有对象发送到数据库,还是仅发送已更改的对象?你是在内存中缓存任何东西,还是每次都要从存储中重新读取?

我要纠正我自己,Marc Gravall指出,第一次迭代需要构建模型,所以我做了一些测试,对XML和二进制进行了平均1000次序列化和反序列化。我先用Compact Framework DLL的v2进行了测试,然后用v3.5 DLL进行了测试。以下是我得到的,时间单位为毫秒:

.NET 2.0
================================ XML ====== Binary ===
Serialization 1st Iteration      3236       5508
Deserialization 1st Iteration    1501       318
Serialization Average            9.826      5.525
Deserialization Average          5.525      0.771

.NET 3.5
================================ XML ====== Binary ===
Serialization 1st Iteration      3307       5598
Deserialization 1st Iteration    1386       200
Serialization Average            10.923     5.605
Deserialization Average          5.605      0.279

XML通常处理速度慢,占用大量空间。已经有许多不同的尝试来解决这个问题,而今天最流行的似乎是在gzip文件中删除这些内容,比如


已经证明gzip方法不太理想,他们和其他人一直在研究一种更好的二进制序列化方法,适合于快速处理和压缩传输。

您的方法的主要开销是实际生成XmlSerializer类。创建serialiser是一个耗时的过程,对于每种对象类型,只应执行一次。尝试缓存序列化服务器,看看这是否能提高性能

按照这个建议,我发现我的应用程序的性能有了很大的提高,这使我能够继续使用XML序列化


希望这会有所帮助。

我正在使用CF2.0,并且我已经为需要序列化的对象的属性添加了属性。是否可以在CF3.5中尝试它(使用CF3.5二进制文件),看看是否可以修复它?好的,我刚刚在CF3.5上运行了测试,并看到CF2的性能显著提高;对于序列化和反序列化,二进制执行得更快。不幸的是,我与CF2联系在一起,所以可能需要重新思考。只是为了澄清我上面的措辞。。我的意思是我在CF3.5中看到了显著的性能提升;CF2速度较慢。抱歉..请注意,我看错了性能报告!下面是我在测试一个具有3个属性的简单实体时得到的结果:XML序列化317ms XML反序列化:7ms二进制序列化:147ms二进制反序列化:19msI打算建议使用Red Gate ANTS profiler,但它不适用于Compact框架(在google“Red Gate ANTS profiler Compact”上搜索)这些对象存储在SQLCe数据库中,但我可以清楚地看到,序列化和反序列化是对性能的影响,而不是数据库交互。内容也缓存在内存中,但需要将内容存储在数据库中,以便在应用程序会话之间检索。