.net - 序列化性能差的可能解决方案

标签 .net asp.net performance serialization reflection

我最近使用进程外 session 状态对 ASP.NET 应用程序进行了一些性能测试和分析 - 在 Web 场上使用 session 状态时这是必要的,以便可以在任何 Web 服务器上检索状态,例如如果后续 HTTP 请求由于 session 不是“粘性”或原始服务器已关闭等而到达不同的服务器。

令我惊讶的是,当我以满负荷运行 Web 服务器并分析 CPU 使用率时,大约 99% 的 CPU 时间都花在了序列化和反序列化 session 状态上。随后我们实现了一个定制的“缓存”状态服务器;这总是序列化状态,但也将状态保留在内存中,这样如果您使用粘性 session ,则大多数情况下都不必反序列化状态。这将服务器吞吐量提高了 2 倍;但是,序列化仍占 CPU 时间的 98% 或更多。

通过在序列化之前“修剪” session 状态中的对象之间不必要的对象引用,我们在速度上获得了一些进一步的改进——在反序列化时手动修复引用。这将速度提高了 10-20% 左右。这里的原因是,一些性能损失是由于内置的​​序列化必须遍历对象指针的图,这变成了具有更多指针的更复杂的任务。

继续调查,我们为我们的一些类编写了定制的序列化例程,而不是依赖于 .Net 的内置序列化。我们发现性能是 大大改进 ,乘以大约 的因子50 倍 .似乎大部分 CPU 负载是由内置的 .Net 序列化引起的,而由于依赖于使用反射来遍历对象指针/图形和提取字段数据,这反过来又很慢。

将我们的性能提高 50 倍是非常诱人的,从而大大降低了 Web 服务器硬件要求(功率要求降低了一个较小但仍然很重要的因素)。目前的选项是:

1)编写自定义序列化。由于任务的复杂性和它产生的维护开销,这是一个问题,也就是说,对类状态的任何更改都需要对序列化/反序列化例程进行更改。

2)一些第三方解决方案。也许某些产品会在构建时自动生成状态保存/加载代码,从而无需使用反射。

我很想知道是否有人知道第三方解决方案,或者遇到过这个问题,因为我没有从互联网搜索中找到任何提及。

更新:
有些人提出了一种介于默认内置序列化和纯定制序列化例程之间的中间解决方案。这个想法是您为影响性能最大的类实现自定义序列化,例如覆盖 ISerializable。这是一种有趣且有前途的方法;但是,我仍然认为可以完全替代内置序列化,而无需编写和维护任何自定义代码——这不能在运行时完成,因为查询对象和访问私有(private)数据需要反射。但理论上可以对已构建的程序集进行后处理并注入(inject)新方法作为额外的构建步骤。一些分析器使用这种方法在由 C# 编译器构建后将分析代码注入(inject)到程序集中。此外,我/think/我在某处读到 .Net 框架支持将方法注入(inject)类 - 因此可能会处理所有与 IL 相关的问题。

最佳答案

不幸的是,我只知道选项一和 tbh 可能会开始变得非常痛苦。

但它只做你想做的事,所以它会尽可能快。

祝你好运。

关于.net - 序列化性能差的可能解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1487724/

相关文章:

c# - 在 ASP.NET Core 2.0 中找不到 AddJsonOptions

c# - 将小数格式化为两位或整数

c# - 如何使用 ASP.NET 或其他方式阻止浏览器关闭?

asp.net - Thinktecture.IdentityModel 与 SimpleMembership

java - 数据结构 : Which should I use for these conditions?

javascript - 两个 Trie 节点之间的最短路径

c# - Entity Framework 3.5 动态创建实体

c# - WCF 使用 MSMQ 发布/订阅

c# - ASP.NET MVC 3 - 如何从数据库填充单选按钮列表

java - 什么更有效率 : Class object or Object[] (object array)?