.Net中各种不同的对象创建方式的速度差异(三)

【菜科解读】
从前面的文章,我们发现以下两点有趣的东西:
1、使用System.Activator的非泛型方法比使用泛型方法快很多(超过200%) 2、使用泛型约束和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)的实现,是这样的:
01 public static object CreateInstance(Type type, bool nonPublic)
02 {
03 if (type == null)
04 {
05 throw new ArgumentNullException("type");
06 }
07 RuntimeType underlyingSystemType = type.UnderlyingSystemType as RuntimeType;
08 if (underlyingSystemType == null)
09 {
10 throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "type");
11 }
12 return underlyingSystemType.CreateInstanceImpl(!nonPublic);
13 }
将这段代码简化一下,就是:
1 public static object CreateInstance(Type type, bool nonPublic)
2 {
3 RuntimeType underlyingSystemType = type.UnderlyingSystemType as RuntimeType;
4 return underlyingSystemType.CreateInstanceImpl(!nonPublic);
5 }
在RuntimeType的CreateInstanceImpl(bool isPublic)中,直接调用了CreateInstanceImpl(bool isPublic, bool skipVisibilityCheck, bool fillCache),这个函数的实现非常有意思,我先把代码贴出来:
01 internal object CreateInstanceImpl(bool publicOnly, bool skipVisibilityChecks, bool fillCache)
02 {
03 RuntimeTypeHandle typeHandle = this.TypeHandle;
04 ActivatorCache cache = s_ActivatorCache;
05 if (cache != null)
06 {
07 ActivatorCacheEntry entry = cache.GetEntry(this);
08 if (entry != null)
09 {
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 }
看起来非常复杂,其实他的实现也也就实现了一个缓存机制:
检查缓存中是否存在这个构造器的委托,如果有,就调用自己的typeHandler的Allocate()方法分配内存,然后调用构造器的委托初始化对象 如果没有缓存,就调用CreateInstanceSlow(bool isPublic, bool fillCache)创建对象,并填充缓存 好吧继续再看看这个CreateInstanceSlow里面干了什么事情。
照例先贴代码吧:
01 private object CreateInstanceSlow(bool publicOnly, bool fillCache)
02 {
03 RuntimeMethodHandle emptyHandle = RuntimeMethodHandle.EmptyHandle;
04 bool bNeedSecurityCheck = true;
05 bool canBeCached = false;
06 bool noCheck = false;
07 this.CreateInstanceCheckThis();
08 if (!fillCache)
09 {
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 }
这个函数写的很复杂,其实实现的东西很简单,其一是调用RuntimeTypeHandler.CreateInstance方法创建对象,然后再填充缓存,以加快下次创建对象的速度。
好了,我们现在已经非常接近事实的真相了。
让我们从另外一个角度出发,看看CreateInstance()干了什么事情。
第二段 从System.Activator.CreateInstance()开始这里,我们先看看他的实现:
1 public static T CreateInstance()
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 }
我们忽然就看到了我们熟悉的身影:RuntimeTypeHandler.CreateInstance方法,终于殊途同归啊。
。
。
也就是说,System.Activator.CreateInstance()相当于调用了CreateInstanceSlow方法(但是没有缓存机制),这应该就是CreateInstance比CreateInstance(Type)慢的主要原因,我们回顾一下这两个方法的时间消耗:System.Activator.CreateInstance(Type):
缓存机制时间消耗 RuntimeTypeHandler.Allocate()内存分配的时间消耗 调用构造器委托初始化数据的时间消耗 这里不考虑缓存失败,调用CreateInstanceSlow的情况,因为这个只会发生一次。
System.Activator.CreateInstance(Type):
调用RuntimeTypeHandler.CreateInstance的时间消耗 在下一篇文章中,我会对这两个函数的性能差异做进一步的分析
.Net,中,各种,不同,的,对象,创建,方式,速度,在俄国的沙皇当中为什么还有一个德国人?这个德国人什么来历
然而,在这几十个沙皇当中能够获得大帝荣誉称号的却仅仅只有两人。
但就在这两人当中,还曾经有过一个德国人。
那么,这究竟是怎么回事呢?下面我们就一起前往查看一番。
事实上,要想这件事情说清楚,就不能不提。
想当初,当彼得大帝打败了瑞典,夺取了波罗的海沿岸广大地区之后,他的野心就更加膨胀了,甚至,他还企图获得整个海域的控制权。
然而,由于当时波罗的海沿岸最大的国家却是德国,而俄国一时间又战胜不了德国,于是乎,彼得大帝就想到了“和亲”,把自己的大女儿嫁给了一位德国的亲王。
而在彼得大帝死后,就由他小女儿做了俄国的沙皇。
然而,令彼得大帝死都没有想到的是,他的小女儿一生竟然没有生孩子。
于是乎,没有办法,他的小女儿,也就是俄国的女沙皇,就去德国将自己的亲外甥领养了过来,并取名彼得三世。
而彼得三世从德国过来做皇太子的时候,也把他的未婚妻索菲亚给从德国带了过来,另取了一个俄国名字叫叶卡特琳娜。
当然,作为德国人,叶卡特琳娜刚到俄国的时候,俄语都不会说,几乎与人无法沟通。
但是,既聪明又机智的叶卡特琳娜却苦学俄语,并研究俄国历史,甚至,他的婆婆越是讽刺她,她就越是孝敬她婆婆。
因此,没过几年,就在宫里扎下了根。
不仅如此,大家都知道,宫里的女人一般都是“母凭子贵”,也许是该着叶卡特琳娜发达,她的肚子非常争气,很快就给皇太子生了一个儿子。
而女沙皇一见自己有了,也是,马上就奖励了她10万卢布。
但是,令谁都没有想到的是,叶卡特琳娜在收到这一笔钱之后,竟然没有用来自己花销,而是收买了朝廷内外的许多贵族和军官,从此,她的势力是越来越大。
此后,当时光走到了1761年底的时候,她的婆婆——女沙皇去世了。
他的丈夫就成为了新的沙皇。
而她也随之成为了皇后。
但是,对于皇后这个职位,叶卡特琳娜却始终并不知足。
于是,她就开始秘密策划,想着要把自己的老公搞掉,由自己继承沙皇。
显然,无怪乎古人说:“最毒不过妇人心”,此话不假。
不过,这可是掉脑袋的事情,必须小心从事。
叶卡特琳娜也不敢大意。
于是,她就先是对内串通了两名近卫军的高级军官,对外买通了一名英国大使,随后,就发动了一起宫廷政变,将自己的丈夫给杀死了。
然后,自己堂而皇之登上了俄国沙皇的宝座。
当然,不过话又说回来了,这个女人确实有能力,比她老公强100倍。
在她统治俄国的34年当中,不但先后打败了土耳其、波兰等国,还攫取了黑海沿岸的大片土地,从而使俄国的领土一下子就扩大了63万平方公里,对于俄国后来的版图作出了重大贡献。
因此,她和一样,被俄国人尊称为“大帝”。
随机文章阿帕奇战斗机杀伤力惊人,海湾战争中摧毁500辆坦克莫比乌斯环象征着什么,无限循环(象征永恒无限的爱情)北极为什么有蚊子,北极蚊子凶猛无比(一口气吸光麋鹿的血)地震为什么预测不到,动物异象预测真的靠谱吗/准确率极低古代骂读书人的时候,为什么要骂穷秀才?
中国古时候最强冷兵器陌刀,人马挡之俱碎
在我国古代,冷兵器的制作工艺达到了巅峰水准,杀伤力巨大的冷兵器以各种各样的形式出现,所谓,各有优劣。
不过说到单兵作战最强的一种兵器,那就是这种出自于唐朝的重型长刀了,也叫做陌刀,这种武器又长又重,是专门针对骑兵的一种重型武器。
著名唐朝将领李陌藩手下就有一只陌刀队,史书上记载,在陌刀阵之前,人马挡之俱碎,可谓是杀力巨大。
众所周知,日本受唐朝文化的影响极大,就连世界著名的武士刀也是仿制唐刀而来,那么陌刀这种杀力巨大的兵器,日本当然也十分想要武装到部队手中,只不过因为陌刀制作成本太高,而且日本也很少有面对大量骑兵的机会,所以并没有成功仿制出陌刀这种武器。
当然,由于陌刀在唐朝是不允许私人收藏和陪葬的,所以现在也已经失传了,目前只能从书上了解到这种兵器,虽然现代有很多武器爱好者在仿造陌刀,但历史上真正的陌刀终究是不可能被百分百还原的。
在古代,兵器的重要性,但并不是能够决定战场胜负的关键,真正的胜负手,主要还是看双方国力,而在局部战役中,那就要看领军主帅的军事谋略了。
在古代战争中,这样的战役比比皆是,以弱胜强全靠主帅卓越的领军能力和军事谋略,所以兵器的先进仅是决定胜负的一个方面而已。
随机文章戊戌变法的意义中国ufo视频震惊世界造谣,画面看起来连三岁小孩都骗不了!探山东双乳峰诅咒,挖山者接连死亡/外形似少女的双乳黑天鹅事件是什么意思,出乎人们意料之外的事(重庆啤酒破产)蒙娜丽莎的背后骷髅头,纪念丽莎·盖拉尔迪尼逝去的儿子