一个快速/紧凑的序列化框架
一个对象序列化/反序列化框架,其速度快数倍,输出紧凑。
引言
NxSerialization 是一个易于使用的对象序列化框架,可替代 .NET 和 Mono 的默认序列化提供程序的功能。NxSerialization 的二进制格式化程序的速度可以比 .NET 和 Mono 的默认二进制格式化程序快 50 倍。这从上面显示的基准应用程序屏幕截图中可以看出。该框架为序列化对象的应用程序提供了三个主要优势。主要优势在于提高空间和时间性能,而增强的安全性是附带的好处。
快速事实
下图包含使用 NxSerialization 随附的 CLI 示例应用程序进行的基准测试结果。重要值以粗体显示。测量的时间是 100 次迭代,每次 100 次运行。在每次运行中,一个指定类型的对象被序列化然后反序列化。这些结果可能因系统配置而异;但是,重要的是要考虑相对差异或本机和 NxSerializer 之间的性能因素。
警告:这些统计数据来自之前的版本,不反映与最新本机格式化程序的比较。
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
命名空间中容器的序列化。 - 支持
BitVector32
、BitArray
和KeyValuePair
对象的序列化。 - 支持
Type
对象的序列化。 - 现在提供代理重定向支持。
- 现在支持动态(即时)代理。
- API 进行重大重构。
- 在各处都进行了许多增强和实用程序。
OpenNxSerialization 1.5 (2008 年 3 月 12 日)
此版本中的更改包括:
- NxFormatter 现在实现了
IRemotingFormatter
。 - 为许多内置类型添加了新的代理。
- 支持
ISerializable
对象的序列化。 - 支持
MarshalByRef
对象的序列化。 - 支持
SerializeAs
和DeserializeAs
函数的泛型版本。 - 流上下文现在可以包含应用程序特定项。
- 在各处都进行了许多增强和实用程序。
OpenNxSerialization 1.0 (CompactSerialization 2.5) (2007 年 7 月 21 日)
再次感谢所有贡献者。此版本中的更改包括:
- CompactSerialization 2.5 现在是 OpenNxSerialization 1.0。
- 支持多个
TypeSurrogateSelector
实例。 - 支持
SerializeAs
和DeserializeAs
函数(速度更快,更紧凑)。 - 读取器不会关闭基础流。
- 支持使用配置文件配置类型。
- 在各处都进行了许多增强和实用程序。
CompactSerialization 2.0 (2006 年 5 月 17 日)
这得益于我收到的精彩反馈。感谢所有贡献者。此版本中的更改包括:
- 支持 .NET 2.0 可空类型。
- 现在可以妥善处理循环引用和共享引用。
- 支持永久/硬类型句柄。
- 支持枚举、
SortedList
等。 - 内部和公共 API 进行重大重构。
- 某些地方性能有所提高,某些地方有所下降 : ).
CompactSerialization 1.0 (2006 年 2 月 15 日)
- 发布了框架的初始版本。