博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CLR VIA反射性能比较的例子
阅读量:5462 次
发布时间:2019-06-15

本文共 7144 字,大约阅读时间需要 23 分钟。

在CLR VIA 的Demo中看到关于反射性能的几个例子,演示了反射操作实例及性能表现。反射的过程其实就是根据要查找的反射信息(字段名,方法名,类名等),在元数据中逐字符匹配的查找字段名,类型名等,然后定位到IL代码编译执行(所以会有大小写区分)。由于元数据是记录了程序集所有类型以及成员的描述信息,所以在其中查找指定的信息是件浪费性能的事情。如何快速匹配到对应的元数据信息,然后定位到IL执行代码去执行,这是本身反射性能提升的直接途径,当然这个过程已经很难优化,但是可以通过缓存管理首次的结果提高效率。类似JIT对IL方法指令的编译,首次编译后保存CLR 元数据相关的结构表中,再下一次执行时直接上次编译的CPU指令。

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; using System.Dynamic; namespace Demo {
class Program {
static void Main(string[] args) {
Type t = typeof(SomeType); //方法一 InvokeMember Invoker.UseInvokeMemberToBindAndInvokeTheMember(t); //方法二 MemberInfo派生类 SetValue->GetSetValueMethod->调用SetValueMethod Invoker.BindToMemberThenInvokeTheMember(t); //方法三 委托操作 看IL的调用栈要比上个浅,因为直接查找了GetMethod,但没有缓存仍然每次都要查找 Invoker.BindToMemberCreateDelegateToMemberThenInvokeTheMember(t); //方法四 Dynamic动态(4.0特性),dynamic经过语法糖编译为IL时对实现了类似方法三的效果, //但是利用了CallSite的委托缓存容器,一次查找重复利用 Invoker.UseDynamicToBindAndInvokeTheMember(t); Console.ReadLine(); } } /// /// 要反射的类型DEMO /// public sealed class SomeType {
private Int32 m_someField; public SomeType(ref Int32 x) { x *= 2; } public override String ToString() { return m_someField.ToString(); } public Int32 SomeProp {
get { return m_someField; } set { m_someField = value; } } public event EventHandler SomeEvent; private void NoCompilerWarnings() {
SomeEvent.ToString(); } } public static class Invoker { /// /// 过滤成员标志 /// private const BindingFlags c_bf = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; /// /// 通过类型的InvokeMember实例的反射成员操作 (最差,次次反射对象) /// /// public static void UseInvokeMemberToBindAndInvokeTheMember(Type t) { // Construct an instance of the Type Object[] args = new Object[] { 12 }; // Constructor arguments Object obj = t.InvokeMember(null, c_bf | BindingFlags.CreateInstance, null, null, args); // Read and write to a field t.InvokeMember("m_someField", c_bf | BindingFlags.SetField, null, obj, new Object[] { 5 }); Int32 v = (Int32)t.InvokeMember("m_someField", c_bf | BindingFlags.GetField, null, obj, null); // Call a method String s = (String)t.InvokeMember("ToString", c_bf | BindingFlags.InvokeMethod, null, obj, null); // Read and write a property try {
t.InvokeMember("SomeProp", c_bf | BindingFlags.SetProperty, null, obj, new Object[] { 0 }); } catch (TargetInvocationException e) {
} t.InvokeMember("SomeProp", c_bf | BindingFlags.SetProperty, null, obj, new Object[] { 2 }); v = (Int32)t.InvokeMember("SomeProp", c_bf | BindingFlags.GetProperty, null, obj, null); // Add and remove a delegate from the event by invoking the event抯 add/remove methods EventHandler eh = new EventHandler(EventCallback); t.InvokeMember("add_SomeEvent", c_bf | BindingFlags.InvokeMethod, null, obj, new Object[] { eh }); t.InvokeMember("remove_SomeEvent", c_bf | BindingFlags.InvokeMethod, null, obj, new Object[] { eh }); } /// /// 通过获取构造实例,获取成员反射类型设置(反射一次对象,效率高于上个) /// MemberInfo派生类 SetValue->GetSetValueMethod->调用SetValueMethod /// /// public static void BindToMemberThenInvokeTheMember(Type t) { // Construct an instance // ConstructorInfo ctor = t.GetConstructor(new Type[] { Type.GetType("System.Int32&") }); ConstructorInfo ctor = t.GetConstructor(new Type[] { typeof(Int32).MakeByRefType() }); Object[] args = new Object[] { 12 }; // Constructor arguments Object obj = ctor.Invoke(args); // Read and write to a field FieldInfo fi = obj.GetType().GetField("m_someField", c_bf); fi.SetValue(obj, 33); // Call a method MethodInfo mi = obj.GetType().GetMethod("ToString", c_bf); String s = (String)mi.Invoke(obj, null); // Read and write a property PropertyInfo pi = obj.GetType().GetProperty("SomeProp", typeof(Int32)); try {
pi.SetValue(obj, 0, null); } catch (TargetInvocationException e) {
} pi.SetValue(obj, 2, null); // Add and remove a delegate from the event EventInfo ei = obj.GetType().GetEvent("SomeEvent", c_bf); EventHandler eh = new EventHandler(EventCallback); // See ei.EventHandlerType ei.AddEventHandler(obj, eh); ei.RemoveEventHandler(obj, eh); } /// /// 通过委托执行实例成员的IL方法(效率高于上个,比较适合批量处理大量未知对象的序列化) /// /// public static void BindToMemberCreateDelegateToMemberThenInvokeTheMember(Type t) { // Construct an instance (You can't create a delegate to a constructor) Object[] args = new Object[] { 12 }; // Constructor arguments Object obj = Activator.CreateInstance(t, args); // NOTE: You can't create a delegate to a field // Call a method MethodInfo mi = obj.GetType().GetMethod("ToString", c_bf); var toString = (Func
)Delegate.CreateDelegate(typeof(Func
), obj, mi); String s = toString(); // Read and write a property PropertyInfo pi = obj.GetType().GetProperty("SomeProp", typeof(Int32)); var setSomeProp = (Action
)Delegate.CreateDelegate(typeof(Action
), obj, pi.GetSetMethod()); try {
setSomeProp(0); } catch (ArgumentOutOfRangeException) {
} setSomeProp(2); var getSomeProp = (Func
)Delegate.CreateDelegate(typeof(Func
), obj, pi.GetGetMethod()); // Add and remove a delegate from the event EventInfo ei = obj.GetType().GetEvent("SomeEvent", c_bf); var addSomeEvent = (Action
)Delegate.CreateDelegate(typeof(Action
), obj, ei.GetAddMethod()); addSomeEvent(EventCallback); var removeSomeEvent = (Action
)Delegate.CreateDelegate(typeof(Action
), obj, ei.GetRemoveMethod()); removeSomeEvent(EventCallback); } ///
/// 动态代理方式UseDynamic,但是利用了CallSite的委托缓存容器,性能要高于方法三 /// ///
public static void UseDynamicToBindAndInvokeTheMember(Type t) { // Construct an instance (You can't create a delegate to a constructor) Object[] args = new Object[] { 12 }; // Constructor arguments dynamic obj = Activator.CreateInstance(t, args); // Read and write a property try { obj.SomeProp = 0; } catch (ArgumentOutOfRangeException ex) { throw ex; } obj.SomeProp = 2; Int32 val = (Int32)obj.SomeProp; // Add and remove a delegate from the event obj.SomeEvent += new EventHandler(EventCallback); obj.SomeEvent -= new EventHandler(EventCallback); } // Callback method added to the event private static void EventCallback(Object sender, EventArgs e) { } } }

 

转载于:https://www.cnblogs.com/mecity/archive/2011/11/12/2246114.html

你可能感兴趣的文章
关于<a></a>标签里嵌套<a></a>标签的bug
查看>>
关于iphone定位的基本知识
查看>>
Hbase配置项粗解
查看>>
.NET 泛型中的逆变 和 协变
查看>>
原创:WordPress调用百度前端公众库jquery
查看>>
SecondaryNameNode合并元信息过程
查看>>
小白Linux下安装Tomcat,及热部署
查看>>
Jzoj5409 Fantasy
查看>>
Jzoj3498 图形变换
查看>>
stm32F4系列库函数版本各模块配置过程
查看>>
Android_(传感器)指南针
查看>>
个人工作总结2
查看>>
E - Valued Keys
查看>>
[WASM] Write to WebAssembly Memory from JavaScript
查看>>
[TypeScript] Model Alternatives with Discriminated Union Types in TypeScript
查看>>
[Redux] Filtering Redux State with React Router Params
查看>>
模块与包
查看>>
fragment的学习
查看>>
<context:annotation-config/>
查看>>
BZOJ4364: [IOI2014]wall砖墙(线段树)
查看>>