国产探花免费观看_亚洲丰满少妇自慰呻吟_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指令了。




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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 大竹县| 蛟河市| 江城| 东山县| 象山县| 乌兰浩特市| 竹溪县| 昌吉市| 怀化市| 资兴市| 镇安县| 台南县| 巴马| 西畴县| 慈利县| 昌乐县| 延庆县| 龙州县| 大洼县| 巫溪县| 托克托县| 汽车| 新田县| 宜州市| 弥渡县| 白玉县| 阿坝县| 墨脱县| 嵊泗县| 定兴县| 上犹县| 孙吴县| 富锦市| 库尔勒市| 新竹县| 罗山县| 沾益县| 咸丰县| 封丘县| 丰镇市| 普洱|