反射(Reflection)的性能分析
【IT168技术文档】
记得老早以前就看到有人把反射称之为“性能杀手",正好目前正在做的erp系统为了实现扩展,系统就是架构在反射的基础之上,数据交互也都是通过反射来实现。
首先系统会产生太多dll,现在刚刚起步,已经高达43个之多,由于erp系统具有很复杂的业务功能,产品在发布阶段很可能产生200甚至更多的dll,且不说这几百个项目在调试的时候,漫长的等待是多么的痛苦,在产品推出去之后,这么多的dll的版本如何维护?多现在为止,除了windows还没有见过dll超过百的系统,难道我们的系统真的比windows还要难?这些暂且不提,先测试一下反射在系统应用的性能情况,测试程序如下:
记得老早以前就看到有人把反射称之为“性能杀手",正好目前正在做的erp系统为了实现扩展,系统就是架构在反射的基础之上,数据交互也都是通过反射来实现。
首先系统会产生太多dll,现在刚刚起步,已经高达43个之多,由于erp系统具有很复杂的业务功能,产品在发布阶段很可能产生200甚至更多的dll,且不说这几百个项目在调试的时候,漫长的等待是多么的痛苦,在产品推出去之后,这么多的dll的版本如何维护?多现在为止,除了windows还没有见过dll超过百的系统,难道我们的系统真的比windows还要难?这些暂且不提,先测试一下反射在系统应用的性能情况,测试程序如下:
被测试类#region 被测试类
using System;
using System.Collections.Generic;
using System.Text;
![]()
namespace ClassLibrary1
......{
public class CTester
......{
public CTester()
......{
a = 10;
}
![]()
![]()
public void test1()
......{
a = (a - 0.0001) * 1.0001;
}
private double a;
public double geta() ......{ return a; }
}
}
#endregion
测试类#region 测试类
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Collections;
![]()
namespace ConsoleApplication2
......{
![]()
public class CTester
......{
public CTester()
......{
a = 10;
}
![]()
![]()
public void test1()
......{
a = (a - 0.0001) * 1.0001;
}
private double a;
public double geta() ......{ return a; }
}
![]()
class Program
......{
private string test1()
......{
int now = System.Environment.TickCount;
![]()
for (int i = 0; i < 1000; i++)
......{
for (int j = 0; j < 100; j++)
......{
CTester aTest = new CTester();
aTest.test1();
![]()
}
}
![]()
string time = (System.Environment.TickCount - now).ToString();
return time;
}
static Hashtable table = new Hashtable();
private string test3()
......{
int now = System.Environment.TickCount;
![]()
for (int i = 0; i < 1000; i++)
......{
for (int j = 0; j < 100; j++)
......{
Type theTest = null;
if (table.ContainsKey("ConsoleApplication2.CTester"))
......{
theTest = table["ConsoleApplication2.CTester"] as Type;
}
else
......{
theTest = Type.GetType("ConsoleApplication2.CTester");
table.Add("ConsoleApplication2.CTester", theTest);
}
ConsoleApplication2.CTester theobj = theTest.InvokeMember(null, BindingFlags.CreateInstance
, null, null, null) as ConsoleApplication2.CTester;
theobj.test1();
}
}
![]()
string time =(System.Environment.TickCount - now).ToString();
return time;
}
private string test2()
......{
int now = System.Environment.TickCount;
for (int i = 0; i < 1000; i++)
......{
for (int j = 0; j < 100; j++)
......{
Type theTest = theTest = Type.GetType("ConsoleApplication2.CTester"); ;
ConsoleApplication2.CTester theobj = theTest.InvokeMember(null, BindingFlags.CreateInstance
, null, null, null) as ConsoleApplication2.CTester;
theobj.test1();
}
}
![]()
string time =(System.Environment.TickCount - now).ToString();
return time;
}
static object InvokeMehod(string FileName,
string MethodName,
object[] Args)
......{
Assembly a = Assembly.LoadFrom(FileName);
![]()
![]()
MethodInfo method = null;
Type HereType = null;
foreach (Module m in a.GetModules())
......{
foreach (Type t in m.GetTypes())
......{
![]()
foreach (MethodInfo mInfo in t.GetMethods())
......{
if (mInfo.Name == MethodName)
......{
ParameterInfo[] pInfo = mInfo.GetParameters();
if (pInfo.Length == Args.Length)
......{
bool same = true;
for (int i = 0; i < pInfo.Length; i++)
......{
if (Args[i] != null && pInfo[i].ParameterType != typeof(object)
&& pInfo[i].ParameterType != typeof(object[]))
......{
if (pInfo[i].ParameterType != Args[i].GetType())
......{
same = false;
}
}
}
if (same)
......{
HereType = t;
method = mInfo;
}
}
}
![]()
if (method != null)
......{
break;
}
}
![]()
if (method != null)
......{
break;
}
}
![]()
if (method != null)
......{
break;
}
}
![]()
if (method == null)
......{
//Log.LogException(typeof(Excute), "没有发现:" + FileName + "/" + MethodName, new Exception("没有发现:" + FileName + "/" + MethodName));
return null;
}
![]()
object ins = null;
if (!method.IsStatic)
......{
ins = a.CreateInstance(HereType.FullName);
}
object RetObject = method.Invoke(ins, Args);
return RetObject;
}
![]()
![]()
private string test5()
......{
int now = System.Environment.TickCount;
for (int i = 0; i < 1000; i++)
......{
for (int j = 0; j < 100; j++)
......{
InvokeMehod(@"D:\ConsoleApplication2\ConsoleApplication2\ConsoleApplication2\bin\Debug\ClassLibrary1.dll", "test1", new object[] ......{ });
}
}
![]()
string time = (System.Environment.TickCount - now).ToString();
return time;
}
static void Main(string[] args)
......{
Program p = new Program();
string ticks = p.test1();
Console.WriteLine("用编译器执行:"+ticks);
string t = p.test2();
Console.WriteLine("用反射执行"+t);
string t1 = p.test3();
Console.WriteLine("优化之后的反射:"+t1);
string t2 = p.test5();
Console.WriteLine("加载程序集并反射:"+t2);
if (ticks.ToString() == "0")
......{
Console.WriteLine("反射/编译: 不在一个级别上面");
}
else
......{
Console.WriteLine("反射/编译 =" + (Convert.ToInt32(t) / Convert.ToInt32(ticks)).ToString());
}
![]()
if (ticks.ToString() == "0")
......{
Console.WriteLine("加载程序集并反射/编译: 不在一个级别上面");
}
else
......{
Console.WriteLine("加载程序集并反射/编译 =" + (Convert.ToInt32(t2) / Convert.ToInt32(ticks)).ToString());
}
![]()
![]()
Console.WriteLine("加载程序集并反射/反射 =" + (Convert.ToInt32(t2) / Convert.ToInt32(t)).ToString());
![]()
Console.Read();
}
}
}
#endregion
测试结果为:

0
相关文章