这是很好的使用方法:Object.GetType()== typeof运算(类型)或对象的类型? [英] Which is good to use: Object.GetType() == typeof(Type) or Object is Type?

查看:163
本文介绍了这是很好的使用方法:Object.GetType()== typeof运算(类型)或对象的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道哪种说法是非常有用的从的查看性能点的是否使用



  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 versus int 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, if A : B than the equality test will fail for A.GetType() == typeof(B) whereas A is B will succeed.
  • If the object is null, it will throw a System.NullReferenceException. In the second case, it will return false.

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 that Object can't/is always of type Type.

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 and ret 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 for isinst. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆