用法很簡單:
ReflectionSugar rs = new ReflectionSugar(100);//緩存100秒 ,可以不填默認不緩存
rs.有嘛點嘛
性能測試:
性能測試類源碼:
http://www.cnblogs.com/sunkaixuan/p/4540840.html
using SyntacticSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Test.IO
{
public partial class ReflectionTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//性能測試類
PerformanceTest p = new PerformanceTest();
p.SetCount(100000);//循環次數(默認:1)
p.SetIsMultithread(false);//是否啟動多線程測試 (默認:false)
/******************************CreateInstance********************************/
//帶cache
p.Execute(
i =>
{
CreateInstanceByCache();//調用函數
},
message => { Response.Write(message); }); //總共執行時間:0.09901秒
//不帶cache
p.Execute(
i =>
{
CreateInstanceNoCache();//調用函數
},
message => { Response.Write(message); }); //總共執行時間:0.32002秒
/******************************ExecuteMethod********************************/
//帶cache
p.Execute(
i =>
{
ExecuteMethodByCache();//調用函數
},
message => { Response.Write(message); }); //總共執行時間:0.36202秒
//不帶cache
p.Execute(
i =>
{
ExecuteMethodNoCache();//調用函數
},
message => { Response.Write(message); }); //總共執行時間:1.35508秒
/******************************ExecuteMethod********************************/
//帶cache
p.Execute(
i =>
{
ExecuteMethodByCache();//調用函數
},
message => { Response.Write(message); }); //總共執行時間:0.36202秒
//不帶cache
p.Execute(
i =>
{
ExecuteMethodNoCache();//調用函數
},
message => { Response.Write(message); }); //總共執行時間:1.35508秒
/******************************LoadFile********************************/
//帶cache
p.Execute(
i =>
{
LoadFileByCache();//調用函數
},
message => { Response.Write(message); }); //總共執行時間:0.11801
//不帶cache
p.Execute(
i =>
{
LoadFileNoCache();//調用函數
},
message => { Response.Write(message); }); //總共執行時間:4.89628秒
//還有其它方法就不測試了
}
//獲取實列
private static void CreateInstanceByCache()
{
ReflectionSugar rs = new ReflectionSugar(100);//緩存100秒
var f = rs.CreateInstance<FileSugar>("SyntacticSugar.FileSugar", "SyntacticSugar");
}
//獲取實列
private static void CreateInstanceNoCache()
{
string path = "SyntacticSugar.FileSugar,SyntacticSugar";//命名空間.類型名,程序集
Type o = Type.GetType(path);//加載類型
FileSugar obj = (FileSugar)Activator.CreateInstance(o, true);//根據類型創建實例
}
//執行函數
private static void ExecuteMethodByCache()
{
ReflectionSugar rs = new ReflectionSugar(100);//緩存100秒
var path = rs.ExecuteMethod("SyntacticSugar", "FileSugar", "GetMapPath", "~/");
}
//執行函數
private static void ExecuteMethodNoCache()
{
ReflectionSugar rs = new ReflectionSugar(0);//緩存0秒
var path = rs.ExecuteMethod("SyntacticSugar", "FileSugar", "GetMapPath", "~/");
}
//加載程序集
private static void LoadFileByCache()
{
ReflectionSugar rs = new ReflectionSugar(100);//緩存100秒
Assembly ams = rs.LoadFile(@"D:\學習\SyntacticSugar\SyntacticSugar\bin\Debug\SyntacticSugar.dll");
}
//加載程序集
private static void LoadFileNoCache()
{
ReflectionSugar rs = new ReflectionSugar(0);//緩存100秒
Assembly ams = rs.LoadFile(@"D:\學習\SyntacticSugar\SyntacticSugar\bin\Debug\SyntacticSugar.dll");
}
}
}
反射類源碼:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.Caching;
namespace SyntacticSugar
{
/// <summary>
/// ** 描述:反射通用類
/// ** 創始時間:2010-2-28
/// ** 修改時間:-
/// ** 修改人:sunkaixuan
/// ** 使用說明: http://www.cnblogs.com/sunkaixuan/p/4635710.html
/// </summary>
public class ReflectionSugar
{
public static int Minutes = 60;
public static int Hour = 60 * 60;
public static int Day = 60 * 60 * 24;
private int _time = 0;
private bool _isCache { get { return _time > 0; } }
/// <summary>
/// 緩存時間,0為不緩存(默認值:0秒,單位:秒)
/// </summary>
public ReflectionSugar(int time = 0)
{
_time = time;
}
/// <summary>
/// 創建對象實例
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="fullName">命名空間.類型名</param>
/// <param name="assemblyName">程序集(dll名稱)</param>
/// <returns></returns>
public T CreateInstance<T>(string fullName, string assemblyName)
{
string key = GetKey("CreateInstance1", fullName, assemblyName);
if (_isCache)
if (ContainsKey(key))
{
return Get<T>(key);
}
string path = fullName + "," + assemblyName;//命名空間.類型名,程序集
Type o = Type.GetType(path);//加載類型
object obj = Activator.CreateInstance(o, true);//根據類型創建實例
var reval = (T)obj;
if (_isCache)
Add<T>(key, reval, _time);
return reval;//類型轉換並返回
}
/// <summary>
/// 創建對象實例
/// </summary>
/// <typeparam name="T">要創建對象的類型</typeparam>
/// <param name="assemblyName">類型所在程序集名稱(dll名稱)</param>
/// <param name="nameSpace">類型所在命名空間</param>
/// <param name="className">類型名</param>
/// <returns></returns>
public T CreateInstance<T>(string assemblyName, string nameSpace, string className)
{
string key = GetKey("CreateInstance2", assemblyName, nameSpace, className);
if (_isCache)
if (ContainsKey(key))
{
return Get<T>(key);
}
try
{
string fullName = nameSpace + "." + className;//命名空間.類型名
//此為第一種寫法
object ect = Assembly.Load(assemblyName).CreateInstance(fullName);//加載程序集,創建程序集裡面的 命名空間.類型名 實例
var reval = (T)ect;//類型轉換並返回
if (_isCache)
Add<T>(key, reval, _time);
return reval;
//下面是第二種寫法
//string path = fullName + "," + assemblyName;//命名空間.類型名,程序集
//Type o = Type.GetType(path);//加載類型
//object obj = Activator.CreateInstance(o, true);//根據類型創建實例
//return (T)obj;//類型轉換並返回
}
catch
{
//發生異常,返回類型的默認值
var reval = default(T);
if (_isCache)
Add<T>(key, reval, _time);
return reval;//類型轉換
}
}
/// <summary>
/// 加載程序集
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public Assembly LoadFile(string path)
{
string key = GetKey("LoadFile", path);
if (_isCache)
if (ContainsKey(key))
{
return Get<Assembly>(key);
}
Assembly asm = Assembly.LoadFile(path);
if (_isCache)
Add<Assembly>(key, asm, _time);
return asm;
}
/// <summary>
/// 獲取類型根據程序集
/// </summary>
/// <param name="asm">Assembly對象</param>
/// <returns></returns>
public Type GetTypeByAssembly(Assembly asm, string nameSpace, string className)
{
string key = GetKey("GetTypeByAssembly", nameSpace, className);
if (_isCache)
if (ContainsKey(key))
{
return Get<Type>(key);
}
Type type = asm.GetType(nameSpace + "." + className);
if (_isCache)
Add<Type>(key, type, _time);
return type;
}
/// <summary>
/// 返回當前 System.Type 的所有公共屬性。
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public PropertyInfo[] GetProperties(Type type)
{
string key = GetKey("GetProperties", type.FullName);
if (_isCache)
if (ContainsKey(key))
{
return Get<PropertyInfo[]>(key);
}
var reval = type.GetProperties();
if (_isCache)
Add<PropertyInfo[]>(key, reval, _time);
return reval;
}
/// <summary>
/// 根據字符執行方法
/// </summary>
/// <param name="nameSpace">命名空間</param>
/// <param name="className">類名</param>
/// <param name="MethodName">方法名</param>
/// <param name="parameters">參數</param>
/// <returns>返回object類型</returns>
public object ExecuteMethod(string nameSpace, string className, string MethodName, params object[] parameters)
{
string key = GetKey("ExecuteMethod", nameSpace, className, MethodName, parameters.Length.ToString());
MethodInfo methodinfo = null;
if (_isCache&&ContainsKey(key))
{
methodinfo = Get<MethodInfo>(key);
}
else
{
//動態從程序集中查找所需要的類並使用系統激活器創建實例最後獲取它的Type
Type type = Assembly.Load(nameSpace).CreateInstance(nameSpace + "." + className).GetType();
//定義參數的個數,順序以及類型的存儲空間;
Type[] parametersLength;
if (parameters != null)
{
//如果有參數創建參數存儲空間並依次設置類型
parametersLength = new Type[parameters.Length];
int i = 0;
foreach (object obj in parameters)
{
parametersLength.SetValue(obj.GetType(), i);
i++;
}
}
else
{
//沒有參數就為空
parametersLength = new Type[0];
}
//查找指定的方法
methodinfo = type.GetMethod(MethodName, parametersLength);
if (_isCache)
Add<MethodInfo>(key, methodinfo, _time);
}
//如果是靜態方法就執行(非靜態我沒試過)
if (methodinfo.IsStatic)
{
//調用函數
return methodinfo.Invoke(null, parameters);
}
return null;
}
#region helper
private string GetKey(params string[] keyElementArray)
{
return string.Join("", keyElementArray);
}
/// <summary>
/// 插入緩存
/// </summary>
/// <param name="key"> key</param>
/// <param name="value">value</param>
/// <param name="cacheDurationInSeconds">過期時間單位秒</param>
private void Add<V>(string key, V value, int cacheDurationInSeconds)
{
Add(key, value, cacheDurationInSeconds, CacheItemPriority.Default);
}
/// <summary>
/// 插入緩存.
/// </summary>
/// <param name="key">key</param>
/// <param name="value">value</param>
/// <param name="cacheDurationInSeconds">過期時間單位秒</param>
/// <param name="priority">緩存項屬性</param>
private void Add<V>(string key, V value, int cacheDurationInSeconds, CacheItemPriority priority)
{
string keyString = key;
HttpRuntime.Cache.Insert(keyString, value, null, DateTime.Now.AddSeconds(cacheDurationInSeconds), Cache.NoSlidingExpiration, priority, null);
}
/// <summary>
/// 插入緩存.
/// </summary>
/// <param name="key">key</param>
/// <param name="value">value</param>
/// <param name="cacheDurationInSeconds">過期時間單位秒</param>
/// <param name="priority">緩存項屬性</param>
private void Add<V>(string key, V value, int cacheDurationInSeconds, CacheDependency dependency, CacheItemPriority priority)
{
string keyString = key;
HttpRuntime.Cache.Insert(keyString, value, dependency, DateTime.Now.AddSeconds(cacheDurationInSeconds), Cache.NoSlidingExpiration, priority, null);
}
/// <summary>
/// key是否存在
/// </summary>
/// <param name="key">key</param>
/// <returns> /// 存在<c>true</c> 不存在<c>false</c>. /// /// </returns>
private bool ContainsKey(string key)
{
return HttpRuntime.Cache[key] != null;
}
/// <summary>
///獲取Cache根據key
/// </summary>
private V Get<V>(string key)
{
return (V)HttpRuntime.Cache[key];
}
#endregion
//PropertyInfo GET SET說明
//T.GetProperty("key").GetValue(obj, null); //read a key value
//T.GetProperty("key").SetValue(obj, "", null); //write a value to key
////注意如果是字典
//T.GetProperty("Item").GetValue(obj, new [] {"id"}); //先拿Item 然後才通過 new[] {這裡放指定的key}
}
}
總結:
只要不反射外部DLL文件緩存可以提高3倍性能,如果是反射外部DLL文件可以提高40倍以上,這只是我的測試結果 循環次數超多性能差距越大