65.9K
CodeProject 正在变化。 阅读更多。
Home

一个快速/紧凑的序列化框架

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.85/5 (33投票s)

2006年2月22日

GPL3

5分钟阅读

viewsIcon

296770

downloadIcon

1247

一个对象序列化/反序列化框架,其速度快数倍,输出紧凑。

引言

NxSerialization 是一个易于使用的对象序列化框架,可替代 .NET 和 Mono 的默认序列化提供程序的功能。NxSerialization 的二进制格式化程序的速度可以比 .NET 和 Mono 的默认二进制格式化程序快 50 倍。这从上面显示的基准应用程序屏幕截图中可以看出。该框架为序列化对象的应用程序提供了三个主要优势。主要优势在于提高空间和时间性能,而增强的安全性是附带的好处。

快速事实

下图包含使用 NxSerialization 随附的 CLI 示例应用程序进行的基准测试结果。重要值以粗体显示。测量的时间是 100 次迭代,每次 100 次运行。在每次运行中,一个指定类型的对象被序列化然后反序列化。这些结果可能因系统配置而异;但是,重要的是要考虑相对差异或本机和 NxSerializer 之间的性能因素。

警告:这些统计数据来自之前的版本,不反映与最新本机格式化程序的比较。

Size based comparison of .NET and NxSerialization formatters

.NET 和 NxSerialization 格式化程序的基于大小的比较

Time based comparison of .NET and NxSerialization formatters

.NET 和 NxSerialization 格式化程序的基于时间的比较

3.0 版本有哪些新内容?

此版本没有什么实质性的新内容,除了包含 Remoting 子系统和一些未完成的功能。在长期不活动之后,以及收到许多关于发布 Remoting 特定部分的查询之后,我最终决定发布我开发文件夹中的所有内容,这可能是最后一个版本。

一个有趣的观察是,CLR 的最新版本本机格式化程序已得到很大改进,过去平均快 5 倍的速度增益现在已大大减少。因此,上述统计数据不再能代表与最新 .NET 版本进行的比较。这也意味着该工具包可能已经过了它的黄金时期 :)

未完成的功能

EAR - (Emit Avoid Reflection - 发射避免反射)

一些代理具有 EAR 属性,当设置为 true 时,它使用动态 IL 来促进对象创建,并避免了众所周知的并非超快速的 Activator.CreateInstance。支持尚处于早期阶段,未经严格测试,因此可能会出现问题。此外,没有办法从外部配置 EAR,如果您想尝试,需要修改源代码。

Remoting

理论上,在 Remoting 接收器中使用 NxSerialization 可以加速 Remoting 代码——尽管网络延迟可能会掩盖它——但令人惊讶的是,结果总是恰恰相反(这就是我从未发布它的原因)。HTTP 通道(缺少某些功能)以及根本无效的通道安全也存在问题。

System.Data.* 的代理

尚未实现——尽管这是一项直接的任务。

我很想知道是否还有人觉得它有用,并且能够发现 Remoting 减速的缺点并提出修复建议。一如既往,非常欢迎您的反馈!

使用框架

应用程序对象可以通过两种方式与框架集成。通过为对象类型编写代理并向框架注册代理,或者通过实现 INxSerializable。框架为实现 INxSerializable 的类型提供了内置代理。对于未知类型,使用本机 .NET 序列化。

以下代码示例演示了一个实现 INxSerializable 的类型。请注意底部注册类型的行。

// Sample class that implements INxSerializable
[Serializable]
class SampleCompactableClass : INxSerializable
{
   private String title = "SampleCompactableClass";

   void INxSerializable.Serialize(INxBinaryWriter w)
   {
      w.Write(title);
   }

   void INxSerializable.Deserialize(INxBinaryReader r)
   {
      title = r.ReadString();
   }
}

...
// Register the class with the framework.
NxFormatterServices.Default.RegisterKnownType(typeof(SampleCompactableClass));

以下代码示例演示了一个未实现 INxSerializable 的另一类型的示例代理。使用代理是框架能够紧凑序列化 .NET 原生类型的唯一方法。

// Sample surrogate for SampleSurrogatedClass
class SampleSurrogate : NxSerializationSurrogate
{
   public SampleSurrogate() : base(typeof(SampleSurrogatedClass)) {}

   public override object Read(INxBinaryReader r)
   {
      SampleSurrogatedClass obj = new SampleSurrogatedClass();
      obj.title = r.ReadString();
      return obj;
   }

   public override void Write(INxBinaryWriter w, object graph)
   {
      SampleSurrogatedClass obj = (SampleSurrogatedClass) graph;
      w.Write(obj.title);
   }
}

// Sample class that does not implement INxSerializable
[Serializable]
class SampleSurrogatedClass
{
   internal string title = "SampleSurrogatedClass";
}

...
// Register the surrogate with the framework.
NxTypeSurrogateSelectorNative.Default.Register(new SampleSurrogate());

其他一切都相对容易理解。有关更多信息,请查看源代码中提供的示例基准应用程序。

注释

请注意,对于实际数据大小与类型信息大小之比非常大的对象,不会发生太多内存缩减。尝试一个大小为 100K 的 byte 数组。也有可能出现本机序列化器在 CPU 方面实际上更有效率的情况。

该框架的其他可能性包括:

  • 增强安全性,因为自定义序列化可以保护您的对象数据免遭窥探。除了完全反向工程的可能性之外,对象无法从持久流中反序列化。
  • .NET CLR 1.x 对象可以反序列化为 2.0 对象。A 类型对象可以反序列化为 B 类型对象等。

历史

OpenNxSerialization 2.0 (2008 年 8 月 8 日)

此版本中的更改包括:

  • 数组和集合的序列化现在速度明显加快。
  • 为许多内置类型添加了新的代理。
  • 支持 System.Collections.Generic 命名空间中容器的序列化。
  • 支持 BitVector32BitArrayKeyValuePair 对象的序列化。
  • 支持 Type 对象的序列化。
  • 现在提供代理重定向支持。
  • 现在支持动态(即时)代理。
  • API 进行重大重构。
  • 在各处都进行了许多增强和实用程序。

OpenNxSerialization 1.5 (2008 年 3 月 12 日)

此版本中的更改包括:

  • NxFormatter 现在实现了 IRemotingFormatter
  • 为许多内置类型添加了新的代理。
  • 支持 ISerializable 对象的序列化。
  • 支持 MarshalByRef 对象的序列化。
  • 支持 SerializeAsDeserializeAs 函数的泛型版本。
  • 流上下文现在可以包含应用程序特定项。
  • 在各处都进行了许多增强和实用程序。

OpenNxSerialization 1.0 (CompactSerialization 2.5) (2007 年 7 月 21 日)

再次感谢所有贡献者。此版本中的更改包括:

  • CompactSerialization 2.5 现在是 OpenNxSerialization 1.0。
  • 支持多个 TypeSurrogateSelector 实例。
  • 支持 SerializeAsDeserializeAs 函数(速度更快,更紧凑)。
  • 读取器不会关闭基础流。
  • 支持使用配置文件配置类型。
  • 在各处都进行了许多增强和实用程序。

CompactSerialization 2.0 (2006 年 5 月 17 日)

这得益于我收到的精彩反馈。感谢所有贡献者。此版本中的更改包括:

  • 支持 .NET 2.0 可空类型。
  • 现在可以妥善处理循环引用和共享引用。
  • 支持永久/硬类型句柄。
  • 支持枚举、SortedList 等。
  • 内部和公共 API 进行重大重构。
  • 某些地方性能有所提高,某些地方有所下降 : ).

CompactSerialization 1.0 (2006 年 2 月 15 日)

  • 发布了框架的初始版本。
© . All rights reserved.