当前位置: 首页 > 编程语言 > C#

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

时间:2023-04-10 12:33:45 C#

静态构造函数会导致性能开销吗?最近在dotnetpearls.com上的一篇文章中读到,静态ctors需要大量的性能。不明白为什么?我认为在大多数用例中,“大量”是一种夸大其词的说法。由于存在/不存在beforeFieldInit标志,拥有静态构造函数(即使它什么也不做)会影响类型初始化时间。当你有一个静态构造函数时,会有更严格的保证。对于大多数代码,我认为这没有太大区别——但如果您紧密循环并访问类的静态成员,则可能会有所不同。就个人而言,我不会太担心它-如果您怀疑它与您的实际应用程序有关,请对其进行测试而不是猜测。微标记可能会夸大此处的效果。值得注意的是,在类型初始化方面,.NET4的行为与以前的版本略有不同——因此任何基准测试都应该真正显示不同版本的相关性。好吧,我只是复制了他的测试。对于DEBUG构建的1000000000次迭代,我得到:与RELEASE构建相同的功能确实突出了一个区别:CLR为静态构造函数的执行提供了非常强大的保证,承诺在类可以运行任何方法之前只调用它们一次在里面。当有多个线程使用该类时,实现此保证相当棘手。查看SSCLI20的CLR源代码,我看到相当大的代码块专门用于提供此保证。它维护一个正在运行的静态构造函数列表,受全局锁保护。一旦它在该列表中获得一个条目,它就会切换到特定于类的锁以确保没有两个线程可以运行构造函数。状态位上的双重检查锁表明构造函数已经在运行。许多令人难以置信的代码提供了异常保证。好吧,这段代码不是免费的。将其添加到cctor本身的执行时间,您会看到一些开销。与往常一样,不要让这个限制您的风格,这个保证也是您不想提供的非常好的保证。修理前测量。我只是做了一个小测试来检查将静态构造函数添加到我的一个类中的效果。我有一个如下所示的基类:publicabstractclassBase{publicabstractTaskDoStuffAsync();问题是,在其中一个实现方法中,该方法什么都不做,所以我可以设置一个预完成的任务并每次都返回它。publicsealedclassTest1:Base{readonlyTask_emptyTask;publicTest1(){TaskCompletionSourcesource=newTaskCompletionSource();source.SetResult(null);_emptyTask=source.Task;}publicoverrideTaskDoStuffAsync(){return_empty}Task;(另一种选择是按需返回任务,但结果总是调用这个方法)这个类的对象被频繁创建,通常是周期性的。看一看,将_emptyTask设为静态字段似乎是有益的,因为它对所有方法都是相同的任务:静态Test2(){TaskCompletionSourcesource=newTaskCompletionSource();source.SetResult(null);_emptyTask=source.Task;}publicoverrideTaskDoStuffAsync(){return_emptyTask;然后我想起了静态构造函数和性能的“问题”,经过一些研究(我就是这样),我决定做一个小的基准测试:Stopwatchsw=newStopwatch();列表test1list=newList(),test2list=newList();for(intj=0;j结果一目了然:测试1:53.07ms.测试2:5.03ms.end所以尽管有了静态构造函数,但是利大于弊。总要权衡一下。以上是C#学习教程:静态构造函数会不会造成性能开销?所有内容分享,如果对大家有用,需要了解更多C#学习教程,希望大家多多关注-本文收集自网络,不代表立场.如涉及侵权,请点击维权联系管理员删除,如需转载请注明出处: