Whidbey中类型检查和Cast的JIT 优化
使用Collection<基类>来存储继承类是一个常见的模式。在理想的设计中,基类应当定义用户所需要使用的所有接口。这样通过多态性,不同的继承类可以有不同的行为。然而在现实中,我们往往需要使用类型检查或Cast来判断对象的具体类型, 然后根据不同的类型进行不同的操作。
if( obj.GetType() == typeof(BaseClass)) {
…
}
或
Derived d = (Derived)baseObj;
或
Derived d =baseObj as Derived;
Whidbey中JIT编译器对这两种情况进行了优化。下面是一段C#代码(仅作说明使用):
using System;
class Test {
public static void
Console.ReadLine();
object o = "abcd";
if(o.GetType() == typeof(string)) {
string s = (string)o;
Console.WriteLine(s);
}
}
}
相应的汇编代码如下:
CLR 1.1:
; code for type check
06f80066 8b350417ac05 mov esi,[05ac1704] ("abcd")
06f8006c 8bce mov ecx,esi
06f8006e 3909 cmp [ecx],ecx
06f80070 ff15b0c3b779 call dword ptr [mscorlib_79980000+0x1fc3b0 (79b7c3b0)] (System.Object.GetType)
06f80076 b9f8dab779 mov ecx,0x79b7daf8 (MT: System.String)
06f8007b 89442404 mov [esp+0x4],eax
06f8007f e8c7152772 call mscorwks!COMClass::GetClassFromHandle (791f164b)
06f80084 8b542404 mov edx,[esp+0x4]
06f80088 3bd0 cmp edx,eax
06f8008a 751c jnz 06f800a8
; code for cast
06f8008c 8bd6 mov edx,esi
06f8008e b9f8dab779 mov ecx,0x79b7daf8 (MT: System.String)
06f80093 e8840b2772 call mscorwks!JIT_ChkCastClass (791f0c1c)
Whidbey:
; code for type check
0377007e 8b351c20ac01 mov esi,[01ac201c] ("abcd")
03770084 8bce mov ecx,esi
03770086 baf4adba78 mov edx,0x78baadf4 (MT: System.String)
0377008b e8204b0876 call mscorwks!JIT_IsObj_Typehandle (797f4bb0)
03770090 85c0 test eax,eax
03770092 743f jz image00400000!Test.Main()+0x63 (037700d3)
;code for cast
03770094 85f6 test esi,esi
03770096 741a jz image00400000!Test.Main()+0x42 (037700b2)
03770098 813ef4adba78 cmp dword ptr [esi],0x78baadf4
0377009e 7502 jnz image00400000!Test.Main()+0x32 (037700a2)
037700a0 eb0e jmp image00400000!Test.Main()+0x40 (037700b0)
037700a2 8bd6 mov edx,esi
037700a4 b9f4adba78 mov ecx,0x78baadf4 (MT: System.String)
037700a9 e8a0522976 call mscorwks!JIT_ChkCastClass (79a0534e)
037700ae 8bf0 mov esi,eax
037700b0 eb00 jmp image00400000!Test.Main()+0x42 (037700b2)
相对与1.1而言,Whidbey上类型检查的汇编代码简单了许多。对常见的对象而言,JIT_IsObj_Typehandle仅仅是将对象MethodTable(储存在每个对象的开头)和一个固定的值进行比较。所以在Whidbey上类型检查速度提高了很多。
Whidbey上Cast的汇编代码反而更大。但是在通常情况下速度会有所提高。原因是如果Cast的成功时,JIT_ChkCastClass不会被调用。JIT_ChkCastClass的基本工作是比较对象的MethodTable和指定的MethodTable,在不匹配时获取父类的MethodTable继续进行比较。所以在类的层次(Hierarchy)很深时,JIT_ChkCastClass会较费时间。
理论上而言。Whidbey所生成的代码还有改进的余地。因为从上下文可以知道这里的Cast一定会成功。所以Cast的代码完全没有必要。希望在以后的版本中能得到改进。
posted on 2004-07-20 10:32:00 by gangp 评论(8) 阅读(3576)