.net - 程序集中类的数量如何影响性能?

标签 .net performance assemblies .net-assembly

我正在从事的项目将为大量类生成代码 - 预计有数百到数千个。 在生成时不知道有多少这些类将被实际访问。

生成的类可以 (1) 全部存在于单个程序集(或可能是少数几个程序集)中,这些程序集将在脚趾消耗过程开始时加载。

...或 (2) 我可以为每个 类生成一个程序集,就像 Java 将每个类编译成一个 *.class 二进制文件一样,并且然后提出一种机制来按需加载程序集。

问题:哪种情况会产生更好的(内存和时间)性能?

我的直觉是,对于情况 (1),加载时间和使用的内存与构成单个整体程序集的类的数量成正比。 OTOH,案例 (2) 伴随着并发症。

如果您知道任何与加载程序集内部相关的资源,尤其是调用了哪些代码(如果有的话!?)以及分配了哪些内存(新加载程序集的簿记),请分享它们。

最佳答案

您正在尝试解决一个不存在的问题,程序集加载在 .NET 中非常得到了高度优化。

毫无疑问,将大型装配体分解成许多较小的装配体是最糟糕的事情。到目前为止,加载程序集的最大开销是查找文件。这是一个冷启动问题,CLR 加载程序因磁盘速度慢而陷入困境,需要检索和搜索目录条目以定位包含文件内容的磁盘扇区。当可以从文件系统缓存中检索程序集数据时,此问题在热启动 时消失。请注意,Java 也不是这样做的,它会将 .class 文件打包到 .jar 中。 .jar 大致相当于程序集。

一旦找到文件,.NET 就会使用操作系统工具来使实际加载程序集数据变得非常便宜。它使用内存映射文件。这只涉及为文件保留虚拟内存,从文件中读取。

读取直到稍后才发生,并且由页面错误完成。任何请求分页虚拟内存操作系统的一个特性。访问虚拟内存会产生页面错误,操作系统从文件中加载数据并将虚拟内存页面映射到 RAM 中。之后程序继续,永远不会意识到它被操作系统打断了。抖动会产生这些页面错误,它会访问程序集中的元数据表来定位方法的 IL。然后从中生成可执行机器代码。

此方案的一个自动好处是您永远不会为程序集中但未被使用的代码付费。抖动根本没有理由查看包含 IL 的文件部分,因此它永远不会真正被读取。

请注意此方案的缺点,第一次使用类确实会因磁盘读取而导致性能命中。这需要以一种或另一种方式支付,在 .NET 中,债务将在最后可能的时刻到期。这就是为什么属性以速度慢而著称的原因。

更大的组件总是比许多更小的组件更好。

关于.net - 程序集中类的数量如何影响性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13418108/

相关文章:

C# Newtonsoft 使用声明反序列化自定义对象?

.net - 如何使用参数进行点赞操作?

c# - 图表系列标签为百分比

.net - 诊断 "Quota Exceeded"Win32Exception

mysql - 什么数据库可以很好地处理 200+GB 的数据?

.net - 在 .NET Compact Framework 中获取程序集的版本而不加载它

regex - 在 MongoDB 集合中查找正则表达式数组的匹配项

c# - Web.config 中的程序集

c# - 为什么 DbParameterCollection 中的三个属性在引用程序集中是抽象的,而在其他情况下是虚拟的?

c# - 当程序集用作子类时,CurrentDomain.AssemblyResolve 不会触发