.NET跨组件性能命中

我正在阅读Bill Wagner的书“ Effective C#” 。 在第32项中,他主张开发人员创建更小,更有凝聚力的组件,可以更容易地重用。 然而,在同一个项目中,他说:

…额外的安全检查也是跨程序集边界完成的。 来自同一程序集的所有代码具有相同的信任级别(不一定是相同的访问权限,但具有相同的真实级别)。 每当代码流穿过程序集边界时,CLR都会执行一些安全检查。 程序流越过汇编边界的次数越少,效率就越高……这些性能问题都不能阻止您分解太大的程序集。 表现罚款很轻微。

我的问题是,是否对Foo.dll中的每个方法调用执行了额外的安全检查,还是仅在第一次加载程序集时执行?

谢谢

.NET中的安全系统非常复杂。 我不确定答案是否乍看之下听起来很简单。 即使您只有一个程序集,仍然会执行安全检查。 当您启动一个在单个.exe中具有所有逻辑的应用程序时,您不会绕过.NET安全检查以进行程序集加载和validation,也不会绕过类型inheritance检查。 但是,一旦针对给定范围validation了安全性,通常不会再次发生(可能存在一些缓解情况会导致重新validation证据。)

多个程序集的行为不会有任何不同。 可能存在一些额外的assembly负载成本和初始类型访问成本,因为每个新assembly将需要那些初始安全检查。 但是,与JIT代码本身的过程相比,这些检查通常会很苍白。

除了基本的程序集加载和类型安全检查之外,您还可能有明确的权限要求。 微软系统命名空间充满了Demand和LinkDemand安全检查,可以validation堆栈上的所有呼叫者(需求)或直接呼叫者(链路需求)是否有权进行呼叫。 (您的代码也应包含此类检查,以确认调用者也具有相应的权限。)无论代码位于何处,本地,另一个程序集,甚至另一个应用程序域的程序集中,都会发生这些安全检查。 。 但是,一旦您接到对其他应用程序域或进程,甚至服务和其他服务器的调用,封送这些调用和建立连接的开销就会高出几个数量级。

在.NET安全性方面,这甚至都不是全部。 一些安全检查比其他安全检查更昂贵。 有些需要凭证,有些则需要证据等。安全性不是你可以推卸的东西……它是现代软件开发的重要组成部分。 我不会太担心安全性的成本……因为它在.NET框架和CLR中得到了很好的实现和优化。 我会尽力确保您的应用程序正确构建和组织。 如果将代码分离成多个程序集是合乎逻辑的,减少了维护,部署和重构工作,那么它的安全性值得花费额外的小额成本。

CLR加载程序集时完成这些安全检查。 加载程序集后,不需要进一步的安全检查。

我还阅读了Bill Wagner的书中的段落并对性能有同样的疑问,因此我对我们目前正在开发的应用程序进行了基准测试:

我们的一个C#类有几十万到三百万的调用。

如果此类位于同一个程序集或另一个程序集中,只要它们位于同一进程和域中的同一台计算机上,则没有区别。 我无法衡量任何重大的性能损失!

当然,如果需要整理呼叫,情况就不同了。 也许非常不同……