当你第一次通过接口调用方法时,.NET必须找出由哪个类型和方法来执行调用。首先会调用一段桩代码(Stub
),为实现了该接口的对象找到正确的方法。经过数次查找之后,CLR
会意识到总是在调用同一个具体类型,Stub
代码会由间接调用简化为几条直接调用的汇编命令。这几条指令被称为Monomorphic Stub
,因为已经知道如何直接调用某个类型的方法,如果调用方总是对同一个类型调用接口方法,那这就是理想的状态。
Monomorphic Stub
也会检测到调用错误。如果调用方用了其他类型的对象,那么CLR
最终会用另一个指向新类型的Monomorphic Stub
替换掉Stub
代码。
如果情况比较复杂,需要调用多种类型,可预测性也不高(比如你用接口类型组成了数组或者集合,里面的具体类型比较多),那么Stub
代码会变成用哈希表来选择方法的Polymorphic Stub
。哈希表的检索速度是很快,但还是没有直接调用Polymorphic Stub
快,而且这个哈希表的大小是收到严格的限制的。如果你的类型过多,Stub
还可能会回到一开始那种泛型查找的代码,那样开销就很高了。
如果以上策略影响到了程序性能,你可以这样进行优化:
--出自【编写高性能的.NET代码】
经测试,当对象越多、类型越多、方法越复杂时,采用抽象类方式可以明显提升程序运行速度。
网友评论