反射(Reflection)的性能分析
記得老早以前就看到有人把反射稱之為“性能殺手",正好目前正在做的erp系統為了實現擴展,系統就是架構在反射的基礎之上,數據交互也都是通過反射來實現。首先系統會產生太多dll,現在剛剛起步,已經高達43個之多,由于erp系統具有很復雜的業務功能,產品在發布階段很可能產生200甚至更多的dll,且不說這幾百個項目在調試的時候,漫長的等待是多么的痛苦,在產品推出去之后,這么多的dll的版本如何維護?多現在為止,除了windows還沒有見過dll超過百的系統,難道我們的系統真的比windows還要難?這些暫且不提,先測試一下反射在系統應用的性能情況,測試程序如下:
//被測試類
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; }
}
}

///測試類
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();
}
}
}
測試結果為:
638倍的性能損失,不知道算大算小,反正項目經理說無所謂。
赫赫,無(。。)者無畏
作者:jillzhang
出處:http://jillzhang.cnblogs.com/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
出處:http://jillzhang.cnblogs.com/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。



浙公網安備 33010602011771號