静态构造函数会导致性能开销吗?

abh*_*ash 15 .net c# static constructor

最近看了在dotnetpearls.com一个文章在这里说,静态构建函数需要性能比较命中的大量.

无法理解为什么?

Jon*_*eet 18

我认为"实质性"在大多数用例中都是夸大其词.

具有静态构造函数(即使它什么都不做)会影响由于beforefieldinit标志的存在/不存在而导致的类型初始化时间.当你有一个静态构造函数时,有更严格的保证.

对于大多数代码,我建议这没有太大区别 - 但如果你是紧密循环并访问类的静态成员,它可能会.就个人而言,我不会太担心它 - 如果你怀疑它与你的实际应用有关,那么测试它而不是猜测.微观标记极有可能夸大这里的效果.

值得注意的是,在类型初始化时,.NET 4的行为与以前的版本有些不同 - 所以任何基准测试都应该真正显示不同的版本以便相关.


Pao*_*olo 11

好吧,我刚刚复制了他的测试.

对于带有DEBUG构建的1000000000次迭代,我得到:

  • 4s为他的静态类与静态构造函数
  • 3.6s相同的类,带有注释掉的静态构造函数
  • 2.9s与非静态类(并在迭代之前创建一个实例)与静态构造函数或不

RELEASE构建相同的功能确实突出了一个区别:

  • 带静态构造函数的静态类:4046.875ms
  • 没有静态构造函数的静态类:484.375ms
  • 具有静态构造函数的实例:484.375ms
  • 没有静态构造函数的实例:484.375ms


Han*_*ant 6

CLR为静态构造函数的执行提供了非常强大的保证,它承诺只调用它们一次,然后才能运行类中的任何方法.当有多个线程使用该类时,实现这种保证是相当棘手的.

看一下SSCLI20的CLR源代码,我看到了相当大的代码块,专门用于提供这种保证.它维护一个运行静态构造函数的列表,受全局锁保护.一旦它在该列表中获得一个条目,它就会切换到一个特定于类的锁,以确保没有两个线程可以运行构造函数.对状态位进行双重检查锁定,指示构造函数已在运行.许多提供异常保证的不可思议的代码.

好吧,这段代码不是免费的.将它添加到cctor本身的执行时间,你会看到一些开销.一如既往,不要让这个抽筋你的风格,这个保证也是一个非常好的,你不想自己提供.在你修复之前测量.