国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

.Net中各種不同的對象創建方式的速度差異(四)

2019-11-17 03:49:06
字體:
來源:轉載
供稿:網友
本文章為本人個人博客相應文章的鏡像:

原文地址: http://www.greatony.com/index.php/2010/02/24/speed-of-object-creation-in-dotnet-iv/

在這片文章中,我們暫時放一放Activator.CreateInstance(Type)和Activator.CreateInstance<T>()之間的性能差異,去探索一下,為什么使用泛型約束的速度和CreateInstance<T>()差不多(用屁股都能猜到應該是直接調用了CreateInstance<T>())。




首先我們寫一個小程序來驗證我們的猜想:

1 using System;
2
3 namespace GenericNew
4 {
5     public class PRogram
6     {
7         public static void Main(string[] args)
8         {
9             CreateInstance<Program>();
10             new Program();
11         }
12     
13         public static T CreateInstance<T>() where T: new()
14         {
15             return new T();
16         }
17     }
18 }


編譯了以后用reflector來查看編譯的結果:

1 public static T CreateInstance<T>() where T: new()
2 {
3     return new T();
4 }
5


看起來沒有什么問題啊,跟寫的時候一樣美妙,也沒有見到System.Activator.CreateInstance<T>()的蹤影。

那么,讓我們切換到msil模式看看:

1 .method public hidebysig static !!T CreateInstance<.ctor T>() cil managed
2 {
3     .maxstack 2
4     .locals init (
5         [0] !!T local,
6         [1] !!T local2)
7     L_0000: nop
8     L_0001: ldloca.s local2
9     L_0003: initobj !!T
10     L_0009: ldloc.1
11     L_000a: box !!T
12     L_000f: brfalse.s L_001c
13     L_0011: ldloca.s local2
14     L_0013: initobj !!T
15     L_0019: ldloc.1
16     L_001a: br.s L_0021
17     L_001c: call !!0 [mscorlib]System.Activator::CreateInstance<!!T>()
18     L_0021: stloc.0
19     L_0022: br.s L_0024
20     L_0024: ldloc.0
21     L_0025: ret
22 }


恩,發現[mscorlib]System.Activator::CreateInstance<!!T>()了,通過分析這段代碼,我們會發現,其實ms對于這個的性能還是做了一定的優化的,這段代碼:



試圖采用值類型的初始化方法初始化對象,并對該對象進行裝箱操作
裝箱失敗的情況下,調用System.Activator.CreateInstance<T>()來創建對象


最后再返回創建好的對象。

那么是不是.net本來就是通過這種方式來創建對象的呢?

我們來對比一下new Program()這條語句的編譯結果:

1 newobj instance void GenericNew.Program::.ctor()



那么為什么c#編譯器沒有采用這個指令來創建泛型類的實例呢?

我們需要參考一下msdn上對于newobj的用法的定義:

http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.newobj(VS.85).aspx

在這里,我們看到,newobj指令的使用方法是 newobj <ctor>

也就是說,它的參數是構造器,而非類型本身; 原因就在于,.Net允許有不同參數的構造器存在,只有指定了構造器,clr才知道要使用哪個構造器來初始化對象。

而,對于一個泛型類,在編譯器是無法知道它的泛型參數的構造器信息的,自然就沒有辦法使用newobj指令了。




這就是事實的真相,在下一篇文章中,我們將去探究,事實的終極真相。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 新晃| 邯郸县| 合山市| 贵南县| 云安县| 新平| 武功县| 开封市| 龙口市| 江津市| 清远市| 垦利县| 琼中| 安丘市| 诏安县| 恩平市| 天气| 嵊泗县| 济宁市| 循化| 汝南县| 宁明县| 玉树县| 泰宁县| 留坝县| 大丰市| 宜兰县| 延寿县| 稻城县| 秦皇岛市| 新邵县| 青神县| 万山特区| 南皮县| 孟村| 喀喇| 鄂尔多斯市| 彭水| 大兴区| 株洲市| 金昌市|