这是很好的使用方法:Object.GetType()== typeof运算(类型)或对象的类型? [英] Which is good to use: Object.GetType() == typeof(Type) or Object is Type?
问题描述
我想知道哪种说法是非常有用的从的查看性能点的是否使用
Object.GetType()== typeof运算(类型):
或
对象的类型为
第二个:
对象的类型为
与字符串
与 INT
一个得到:
//释放
00:00:18.1428040 // Object.GetType()== typeof运算(类型):
00:00:03.9791070 //对象的类型为
//调试
00:00:21.3545510 //Object.GetType()== typeof运算(类型):
00:00:06.2969510 //对象的类型为
//机规格:
//英特尔(R)酷睿(TM)i5-3210M CPU @ 2.50GHz
// 6 GB的RAM内存
//的Ubuntu 14.04(OS)
//运行时间:单声道JIT编译器版本3.2.8
//编译:单声道契
//注:有些后台进程运行这些,但在时间
//不同的是显著足够我猜。
注意:有
>对类型平等检查:换句话说,如果
- 的平等
==
强大的语义差别A:b
比相等测试将为A.GetType失败()= = typeof运算(b)
,而A是b
会成功。
如果对象为 空
,它会抛出一个System.NullReferenceException
。在第二种情况下,它会返回
假
。
块引用>
这是相当逻辑从编译点的观点:在第一个变种,您查询的类型的对象。在这不是真正优化的情况下,你首先做一个函数呼叫,该呼叫则说,它必须返回一个指针型表。
在第二种情况下,你忽略这样的电话:编译器将通过返回类型代码专攻它。而如果
键入
事先知道,它甚至可以制定出一个非常快速的测试。
请注意此外,对于一些琐碎的情况下,
对象是类型
可以进行优化:比如,因为编译器已经可以推导出对象
不能/永远是类型键入
。
更先进
一个可以还分析CIL虚拟机的源代码,用于第一变型中,这是:
IL_0000:ldarg.0
IL_0001:callvirt实例类[mscorlib程序]的System.Type [mscorlib程序] System.Object的::的GetType()
IL_0006:ldtoken [mscorlib程序] System.Int32
IL_000b:调用类[mscorlib程序]的System.Type [mscorlib程序]的System.Type :: GetTypeFromHandle(值类型[mscorlib程序] System.RuntimeTypeHandle)
IL_0010:拨打布尔[mscorlib程序]的System.Type :: op_Equality(类[mscorlib程序] System.Type的,类[mscorlib程序]的System.Type)
IL_0015:RET
对于第二个变量是这样的:
IL_0000:ldarg.0
IL_0001:isinst [mscorlib程序] System.Int32
IL_0006:ldnull
IL_0007:cgt.un
IL_0009:RET
(你可以在其他类型的过程中填写)。现在
ldarg.0
和RET
只是副产品使用方法,因此可以忽略它们。
一个人看到是什么,在第一个变种,一个叫了
的GetType
办法明确,然后调用==
运营商。函数调用是一般的贵。在第二个变种,它会立即检查isinst
。代码需要较少字节并且使用较便宜的方法。虽然,当然性能取决于运行时环境的实施,我认为这是相当安全的,说的第二个变种几乎总是打对性能的第一个。
一个编译器很可能专攻的第一个版本,例如,它运行作为第二个有效率,但单C#编译器似乎并没有做到这一点。也许没有可用的C#编译器会。
的I want to know that which statement is useful from a Performance Point of View whether to use
Object.GetType() == typeof(Type)
or
Object is Type
解决方案The second one:
Object is Type
Tested this 1'000'000'000 times with
string
versusint
one gets://Release 00:00:18.1428040 //Object.GetType() == typeof(Type) 00:00:03.9791070 //Object is Type //Debug 00:00:21.3545510 //Object.GetType() == typeof(Type) 00:00:06.2969510 //Object is Type //Machine specs: //Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz //6 GB RAM memory //Ubuntu 14.04 (OS) //Runtime: Mono JIT compiler version 3.2.8 //Compiler: Mono dmcs //Notes: ran these with some background processes, but the difference in time // is significant enough I guess.
Note: There is a strong semantic difference between the two:
- The equality
==
checks on type equality: in other words, ifA : B
than the equality test will fail forA.GetType() == typeof(B)
whereasA is B
will succeed.- If the object is
null
, it will throw aSystem.NullReferenceException
. In the second case, it will returnfalse
.This is rather logic from a compiler point-of-view: in the first variant, you query the object for its type. In case that's not really optimized, you do a function call first, that call then says it must return a pointer to the type-table.
In the second case, you omit such calls: the compiler will specialize it by returning the type-code. And if the
Type
is known in advance, it can even work out a very fast test for it.Note furthermore that for some trivial cases,
Object is Type
can be optimized: for instance because the compiler can already derive thatObject
can't/is always of typeType
.More advanced
One can also analyze the CIL virtual machine source code, for the first variant, this is:
IL_0000: ldarg.0 IL_0001: callvirt instance class [mscorlib]System.Type [mscorlib]System.Object::GetType() IL_0006: ldtoken [mscorlib]System.Int32 IL_000b: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) IL_0010: call bool [mscorlib]System.Type::op_Equality(class [mscorlib]System.Type, class [mscorlib]System.Type) IL_0015: ret
For the second variant this is:
IL_0000: ldarg.0 IL_0001: isinst [mscorlib]System.Int32 IL_0006: ldnull IL_0007: cgt.un IL_0009: ret
(you can of course fill in other types). Now the
ldarg.0
andret
are simply by-products of using a method, so one can ignore them.What one sees is that in the first variant, one calls the
GetType
method explicitly and then calls the==
operator. Function calls are in general expensive. In the second variant, it checks immediately forisinst
. The code requires less bytes and uses less expensive methods. Although performance of course depends on the implementation of the runtime environment, I think it's rather safe to say the second variant will nearly always beat the first one on performance.A compiler could probably specialize the first variant such that it runs as efficient as the second, but the Mono C# compiler doesn't seem to do this. Probably none of the available C# compilers will.
这篇关于这是很好的使用方法:Object.GetType()== typeof运算(类型)或对象的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!