您好,登錄后才能下訂單哦!
本篇內容主要講解“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進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。