本篇内容主要讲解“CLR Via C#静态构造函数的性能是怎样的”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“CLR Via C#静态构造函数的性能是怎样的”吧!
1 CLR Via C#静态构造函数是私有的(private) ,而且不能人为去修改访问修饰符。
2 CLR Via C#静态构造函数不应该去调用基类的静态构造函数,因为静态字段不会被继承到子类。
3 CLR Via C#静态构造函数在一个类型中有且仅有一个,并且是无参的。
4 CLR Via C#静态构造函数中只能初始化静态字段。
从上面的***点可以知道静态构造函数都是private的,所以不能显示区进行调用,关于JIT何时会去生成调用静态构造函数的代码。存在着两种说法。通常被称为Precise和BeforeFieldInit。
l Precise方式JIT编译器生成调用的时机:***创建类型的代码之前;访问类的非继承字段或成员代码之前。
l BeforeFieldInit方式JIT编译器生成调用的时机:在访问费继承静态字段代码之前。
这两种方式的主要区别就是选择调用静态构造函数的时机是否是确定的,Precise方式CLR会在确定的时刻调用静态构造函数,而BeforeFieldInit方式CLR可以自由选择调用静态构造函数的时机,利用这一点,CLR可以根据类型是否在程序域中加载来选择静态构造函数的调用次数,以便能生成执行更快的代码。
下面来看个类分别用CLR Via C#展现了这两种方式
public class UserPrecise { public static string _name = "内联赋值:oec2003"; static UserPrecise() { _name = "构造函数赋值:oec2003"; } } public class UserBeforeFieldInit { public static string _name = "内联赋值:oec2003"; }
通过IL代码可以看出在UserBeforeFieldInit 的元数据上有BeforeFieldInit的标记,如下图:
CLR Via C# 静态构造函数性能的分析与测试
既然上面提到BeforeFieldInit方式CLR Via C#可以选择调用构造函数的次数从而来生成执行更快的代码,下面就写一段测试代码来看看究竟怎样。
public sealed class Program { static void Main(string[] args) { const Int32 iterations = 1000 * 1000 * 1000; Test1(iterations); Test2(iterations); } private static void Test1(Int32 iterations) { Stopwatch sw = Stopwatch.StartNew(); for (Int32 i = 0; i < iterations; i++) { UserBeforeFieldInit._name = "oec2003"; } Console.WriteLine("Test1-UserBeforeFieldInit 用时:" + sw.Elapsed); sw = Stopwatch.StartNew(); for (Int32 j = 0; j < iterations; j++) { UserPrecise._name = "oec2003"; } Console.WriteLine("Test1-UserPrecise 用时:" + sw.Elapsed); } private static void Test2(Int32 iterations) { Stopwatch sw = Stopwatch.StartNew(); for (Int32 i = 0; i < iterations; i++) { UserBeforeFieldInit._name = "oec2003"; } Console.WriteLine("Test2-UserBeforeFieldInit 用时:" + sw.Elapsed); sw = Stopwatch.StartNew(); for (Int32 j = 0; j < iterations; j++) { UserPrecise._name = "oec2003"; } Console.WriteLine("Test2-UserPrecise 用时:" + sw.Elapsed); } } public class UserBeforeFieldInit { public static string _name; } public class UserPrecise { public static string _name ; static UserPrecise() { _name = "oec2003"; } }
CLR Via C#测试结果如下:
CLR Via C# 静态构造函数性能的分析与测试
从上面结果来看,BeforeFieldInit方式的执行速度还是要快很多,但为什么第二次执行时,两种方式的速度差不多呢?因为经过***次执行后JIT编译器知道类型的构造器已经被调用了,所以第二次执行时不会显示对构造函数进行调用。
到此,相信大家对“CLR Via C#静态构造函数的性能是怎样的”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。