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

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

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

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

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



從前面的文章,我們發現以下兩點有趣的東西:



使用System.Activator的非泛型方法比使用泛型方法快很多(超過200%)
使用泛型約束和new關鍵字創建的速度幾乎和System.Activator的泛型方法的一樣


在這篇文章里,我將會這兩個問題做一個進一步的探究,我使用的工具就是鼎鼎大名的.Net反編譯工具:Reflector,歡迎讀者跟我一起探討造成這個現象的原因。

第一段 從System.Activator.CreateInstance(Type)開始

我們先用Reflector打開.Net Framework 3.5中的mscorlib.dll,看看這里面,微軟是怎么實現的。

首先看看System.Activator.CreateInstance(Type),它直接調用了System.Activator.CreateInstance(Type, Boolean),代碼如下

1 public static object CreateInstance(Type type)
2 {
3     return CreateInstance(type, false);
4 }


那么這個CreateInstance(Type, Boolean)的實現,是這樣的:

1 public static object CreateInstance(Type type, bool nonPublic)
2 {
3     if (type == null)
4     {
5         throw new ArgumentNullException("type");
6     }
7     RuntimeType underlyingSystemType = type.UnderlyingSystemType as RuntimeType;
8     if (underlyingSystemType == null)
9     {
10         throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "type");
11     }
12     return underlyingSystemType.CreateInstanceImpl(!nonPublic);
13 }
14


將這段代碼簡化一下,就是:

1 public static object CreateInstance(Type type, bool nonPublic)
2 {
3     RuntimeType underlyingSystemType = type.UnderlyingSystemType as RuntimeType;
4     return underlyingSystemType.CreateInstanceImpl(!nonPublic);
5 }
6


在RuntimeType的CreateInstanceImpl(bool isPublic)中,直接調用了CreateInstanceImpl(bool isPublic, bool skipVisibilityCheck, bool fillCache),這個函數的實現非常有意思,我先把代碼貼出來:

1 internal object CreateInstanceImpl(bool publicOnly, bool skipVisibilityChecks, bool fillCache)
2 {
3     RuntimeTypeHandle typeHandle = this.TypeHandle;
4     ActivatorCache cache = s_ActivatorCache;
5     if (cache != null)
6     {
7         ActivatorCacheEntry entry = cache.GetEntry(this);
8         if (entry != null)
9         {
10             if ((publicOnly && (entry.m_ctor != null)) && ((entry.m_hCtorMethodHandle.GetAttributes() & MethodAttributes.MemberaccessMask) != MethodAttributes.Public))
11             {
12                 throw new MissingMethodException(Environment.GetResourceString("Arg_NoDefCTor"));
13             }
14             object obj2 = typeHandle.Allocate();
15             if (entry.m_ctor != null)
16             {
17                 if (!skipVisibilityChecks && entry.m_bNeedSecurityCheck)
18                 {
19                     MethodBase.PerformSecurityCheck(obj2, entry.m_hCtorMethodHandle, this.TypeHandle.Value, 0x10000000);
20                 }
21                 try
22                 {
23                     entry.m_ctor(obj2);
24                 }
25                 catch (Exception exception)
26                 {
27                     throw new TargetInvocationException(exception);
28                 }
29             }
30             return obj2;
31         }
32     }
33     return this.CreateInstanceSlow(publicOnly, fillCache);
34 }
35


看起來非常復雜,其實他的實現也也就實現了一個緩存機制:



    檢查緩存中是否存在這個構造器的委托,如果有,就調用自己的typeHandler的Allocate()方法分配內存,然后調用構造器的委托初始化對象
    如果沒有緩存,就調用CreateInstanceSlow(bool isPublic, bool fillCache)創建對象,并填充緩存


好吧繼續再看看這個CreateInstanceSlow里面干了什么事情。

照例先貼代碼吧:

1 PRivate object CreateInstanceSlow(bool publicOnly, bool fillCache)
2 {
3     RuntimeMethodHandle emptyHandle = RuntimeMethodHandle.EmptyHandle;
4     bool bNeedSecurityCheck = true;
5     bool canBeCached = false;
6     bool noCheck = false;
7     this.CreateInstanceCheckThis();
8     if (!fillCache)
9     {
10         noCheck = true;
11     }
12     object obj2 = RuntimeTypeHandle.CreateInstance(this, publicOnly, noCheck, ref canBeCached, ref emptyHandle, ref bNeedSecurityCheck);
13     if (canBeCached && fillCache)
14     {
15         ActivatorCache cache = s_ActivatorCache;
16         if (cache == null)
17         {
18             cache = new ActivatorCache();
19             Thread.MemoryBarrier();
20             s_ActivatorCache = cache;
21         }
22         ActivatorCacheEntry ace = new ActivatorCacheEntry(this, emptyHandle, bNeedSecurityCheck);
23         Thread.MemoryBarrier();
24         cache.SetEntry(ace);
25     }
26     return obj2;
27 }
28


這個函數寫的很復雜,其實實現的東西很簡單,其一是調用RuntimeTypeHandler.CreateInstance方法創建對象,然后再填充緩存,以加快下次創建對象的速度。

好了,我們現在已經非常接近事實的真相了。讓我們從另外一個角度出發,看看CreateInstance<T>()干了什么事情。

第二段 從System.Activator.CreateInstance<T>()開始

這里,我們先看看他的實現:

1 public static T CreateInstance<T>()
2 {
3     bool bNeedSecurityCheck = true;
4     bool canBeCached = false;
5     RuntimeMethodHandle emptyHandle = RuntimeMethodHandle.EmptyHandle;
6     return (T) RuntimeTypeHandle.CreateInstance(typeof(T) as RuntimeType, true, true, ref canBeCached, ref emptyHandle, ref bNeedSecurityCheck);
7 }
8


我們忽然就看到了我們熟悉的身影:RuntimeTypeHandler.CreateInstance方法,終于殊途同歸啊。。。

也就是說,System.Activator.CreateInstance<T>()相當于調用了CreateInstanceSlow方法(但是沒有緩存機制),這應該就是CreateInstance<T>比CreateInstance(Type)慢的主要原因,我們回顧一下這兩個方法的時間消耗:

System.Activator.CreateInstance(Type):



緩存機制時間消耗
RuntimeTypeHandler.Allocate()內存分配的時間消耗
調用構造器委托初始化數據的時間消耗


這里不考慮緩存失敗,調用CreateInstanceSlow的情況,因為這個只會發生一次。

System.Activator.CreateInstance(Type):



調用RuntimeTypeHandler.CreateInstance的時間消耗

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 西乌珠穆沁旗| 安泽县| 古交市| 泾源县| 达尔| 长宁区| 滦南县| 长春市| 胶南市| 伊川县| 如东县| 武川县| 石渠县| 马公市| 伊宁市| 友谊县| 宁明县| 镇雄县| 防城港市| 抚宁县| 梁平县| 蕲春县| 团风县| 东乡族自治县| 济源市| 吉木萨尔县| 长春市| 五常市| 滕州市| 重庆市| 延吉市| 新兴县| 拉孜县| 秦安县| 印江| 永泰县| 读书| 夏津县| 镇沅| 丰县| 永州市|