推薦一個快速反射調用的類

使用傳統的.net反射機制,調用類的方法時,在調用頻率大的情況下,會感覺速度很慢。最近瀏覽盧彥的博客時,找到一個他改進后的反射調用類。試用以后感覺效率明顯提高,特推薦給大家。作者重新實現了,反射調用方法,但是調用接口和.net原有方法一致。而且調用時拋出的異常為所調用類的實際異常,不像傳統方式返回為包裝異常。
文章來源:
http://www.codeproject.com/csharp/FastMethodInvoker.asp

快速反射調用類

using?System;
using?System.Collections.Generic;
using?System.Text;
using?System.Reflection;
using?System.Reflection.Emit;

namespace?FastMethodInvoker
ExpandedBlockStart.gifContractedBlock.gif
{
????
class?FastInvoke
ExpandedSubBlockStart.gifContractedSubBlock.gif????
{
????????
public?delegate?object?FastInvokeHandler(object?target,?object[]?paramters);

????????
static?object?InvokeMethod(FastInvokeHandler?invoke,?object?target,?params?object[]?paramters)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????
{
????????????
return?invoke(null,?paramters);
????????}


????????
public?static?FastInvokeHandler?GetMethodInvoker(MethodInfo?methodInfo)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????
{
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????DynamicMethod?dynamicMethod?
=?new?DynamicMethod(string.Empty,?typeof(object),?new?Type[]?{?typeof(object),?typeof(object[])?},?methodInfo.DeclaringType.Module);
????????????ILGenerator?il?
=?dynamicMethod.GetILGenerator();
????????????ParameterInfo[]?ps?
=?methodInfo.GetParameters();
????????????Type[]?paramTypes?
=?new?Type[ps.Length];
????????????
for?(int?i?=?0;?i?<?paramTypes.Length;?i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????
if?(ps[i].ParameterType.IsByRef)
????????????????????paramTypes[i]?
=?ps[i].ParameterType.GetElementType();
????????????????
else
????????????????????paramTypes[i]?
=?ps[i].ParameterType;
????????????}

????????????LocalBuilder[]?locals?
=?new?LocalBuilder[paramTypes.Length];

????????????
for?(int?i?=?0;?i?<?paramTypes.Length;?i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????locals[i]?
=?il.DeclareLocal(paramTypes[i],?true);
????????????}

????????????
for?(int?i?=?0;?i?<?paramTypes.Length;?i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????il.Emit(OpCodes.Ldarg_1);
????????????????EmitFastInt(il,?i);
????????????????il.Emit(OpCodes.Ldelem_Ref);
????????????????EmitCastToReference(il,?paramTypes[i]);
????????????????il.Emit(OpCodes.Stloc,?locals[i]);
????????????}

????????????
if?(!methodInfo.IsStatic)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????il.Emit(OpCodes.Ldarg_0);
????????????}

????????????
for?(int?i?=?0;?i?<?paramTypes.Length;?i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????
if?(ps[i].ParameterType.IsByRef)
????????????????????il.Emit(OpCodes.Ldloca_S,?locals[i]);
????????????????
else
????????????????????il.Emit(OpCodes.Ldloc,?locals[i]);
????????????}

????????????
if?(methodInfo.IsStatic)
????????????????il.EmitCall(OpCodes.Call,?methodInfo,?
null);
????????????
else
????????????????il.EmitCall(OpCodes.Callvirt,?methodInfo,?
null);
????????????
if?(methodInfo.ReturnType?==?typeof(void))
????????????????il.Emit(OpCodes.Ldnull);
????????????
else
????????????????EmitBoxIfNeeded(il,?methodInfo.ReturnType);

????????????
for?(int?i?=?0;?i?<?paramTypes.Length;?i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????
if?(ps[i].ParameterType.IsByRef)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????????
{
????????????????????il.Emit(OpCodes.Ldarg_1);
????????????????????EmitFastInt(il,?i);
????????????????????il.Emit(OpCodes.Ldloc,?locals[i]);
????????????????????
if?(locals[i].LocalType.IsValueType)
????????????????????????il.Emit(OpCodes.Box,?locals[i].LocalType);
????????????????????il.Emit(OpCodes.Stelem_Ref);
????????????????}

????????????}


????????????il.Emit(OpCodes.Ret);
????????????FastInvokeHandler?invoder?
=?(FastInvokeHandler)dynamicMethod.CreateDelegate(typeof(FastInvokeHandler));
????????????
return?invoder;
????????}


????????
private?static?void?EmitCastToReference(ILGenerator?il,?System.Type?type)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????
{
????????????
if?(type.IsValueType)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????il.Emit(OpCodes.Unbox_Any,?type);
????????????}

????????????
else
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????il.Emit(OpCodes.Castclass,?type);
????????????}

????????}


????????
private?static?void?EmitBoxIfNeeded(ILGenerator?il,?System.Type?type)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????
{
????????????
if?(type.IsValueType)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????il.Emit(OpCodes.Box,?type);
????????????}

????????}


????????
private?static?void?EmitFastInt(ILGenerator?il,?int?value)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????
{
????????????
switch?(value)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????
case?-1:
????????????????????il.Emit(OpCodes.Ldc_I4_M1);
????????????????????
return;
????????????????
case?0:
????????????????????il.Emit(OpCodes.Ldc_I4_0);
????????????????????
return;
????????????????
case?1:
????????????????????il.Emit(OpCodes.Ldc_I4_1);
????????????????????
return;
????????????????
case?2:
????????????????????il.Emit(OpCodes.Ldc_I4_2);
????????????????????
return;
????????????????
case?3:
????????????????????il.Emit(OpCodes.Ldc_I4_3);
????????????????????
return;
????????????????
case?4:
????????????????????il.Emit(OpCodes.Ldc_I4_4);
????????????????????
return;
????????????????
case?5:
????????????????????il.Emit(OpCodes.Ldc_I4_5);
????????????????????
return;
????????????????
case?6:
????????????????????il.Emit(OpCodes.Ldc_I4_6);
????????????????????
return;
????????????????
case?7:
????????????????????il.Emit(OpCodes.Ldc_I4_7);
????????????????????
return;
????????????????
case?8:
????????????????????il.Emit(OpCodes.Ldc_I4_8);
????????????????????
return;
????????????}


????????????
if?(value?>?-129?&&?value?<?128)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????il.Emit(OpCodes.Ldc_I4_S,?(SByte)value);
????????????}

????????????
else
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????il.Emit(OpCodes.Ldc_I4,?value);
????????????}

????????}

????}

}


效果測試程序

using?System;
using?System.Reflection;
using?System.Reflection.Emit;
using?System.Collections.Generic;
using?System.Text;
using?System.Diagnostics;

namespace?FastMethodInvoker
ExpandedBlockStart.gifContractedBlock.gif
{
????
class?Program
ExpandedSubBlockStart.gifContractedSubBlock.gif????
{
????????
static?void?Main(string[]?args)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????
{

????????????Type?t?
=?typeof(Person);
????????????MethodInfo?methodInfo?
=?t.GetMethod("Say");
????????????Person?person?
=?new?Person();
????????????
string?word?=?"hello";
????????????Person?p?
=?null;
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
object[]?param?=?new?object[]?{?word,?p,?3?};
????????????
int?TestTimes?=?100000;?//測試次數,可自行調節看效果

ContractedSubBlock.gifExpandedSubBlockStart.gif????????????
傳統方式反射#region?傳統方式反射
????????????
try
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????Stopwatch?watch?
=?new?Stopwatch();
????????????????watch.Start();
????????????????
for?(int?i?=?0;?i?<?TestTimes;?i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????????
{
????????????????????methodInfo.Invoke(person,?param);
????????????????}

????????????????watch.Stop();
????????????????Console.WriteLine(TestTimes.ToString()?
+?"?times?invoked?by?Reflection:?"?+?watch.ElapsedMilliseconds?+?"ms");
????????????}

????????????
catch?(System.Exception?ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????Console.WriteLine(
"傳統方式反射?直接錯誤:"?+?ex.Message);
????????????????Console.WriteLine(
"傳統方式反射?內部錯誤:"?+?ex.InnerException.Message);
????????????}

????????????
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif????????????
快速反射#region?快速反射
????????????
try
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????Stopwatch?watch1?
=?new?Stopwatch();
????????????????FastInvoke.FastInvokeHandler?fastInvoker?
=?FastInvoke.GetMethodInvoker(methodInfo);
????????????????watch1.Start();
????????????????
for?(int?i?=?0;?i?<?TestTimes;?i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????????
{
????????????????????fastInvoker(person,?param);
????????????????}

????????????????watch1.Stop();
????????????????Console.WriteLine(TestTimes.ToString()?
+?"?times?invoked?by?FastInvoke:?"?+?watch1.ElapsedMilliseconds?+?"ms");
????????????}

????????????
catch?(System.Exception?ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????Console.WriteLine(
"快速反射?錯誤:"?+?ex.Message);
????????????}

????????????
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif????????????
直接調用#region?直接調用
????????????
try
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????Stopwatch?watch2?
=?new?Stopwatch();
????????????????watch2.Start();
????????????????
for?(int?i?=?0;?i?<?TestTimes;?i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????????
{
????????????????????person.Say(
ref?word,?out?p,?3);
????????????????}

????????????????watch2.Stop();
????????????????Console.WriteLine(TestTimes.ToString()?
+?"?times?invoked?by?DirectCall:?"?+?watch2.ElapsedMilliseconds?+?"ms");
????????????}

????????????
catch?(System.Exception?ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????????
{
????????????????Console.WriteLine(
"直接調用?錯誤:"?+?ex.Message);
????????????}

????????????
#endregion

????????????
????????????Console.ReadLine();
????????}

????}


????
public?class?Person
ExpandedSubBlockStart.gifContractedSubBlock.gif????
{
????????
public?void?Say(ref?string?word,?out?Person?p,?int?avi)
ExpandedSubBlockStart.gifContractedSubBlock.gif????????
{
????????????word?
=?"ttt"?+?avi.ToString();
????????????p?
=?new?Person();

????????????
//throw?new?System.Exception("出錯了哦");
????????}

????}

}

轉載于:https://www.cnblogs.com/haoliansheng/archive/2009/06/01/1493909.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/276513.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/276513.shtml
英文地址,請注明出處:http://en.pswp.cn/news/276513.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CMake 構建項目Android NDK項目基礎知識

本篇文章將介紹如何使用 CMake 構建實現你的第一個 NDK 項目。 ##前言 你好&#xff01;歡迎來到我的的學習筆記分享系列&#xff0c;第一次給大家分享的是 Android NDK 開發的學習筆記&#xff0c;讓我們先開始了解 NDK 的構建方式吧&#xff01; NDK 構建方式有兩種&#xff…

linux installaccess Nessus-5.2.4

1、Download: http://www.tenable.com/products/nessus/select-your-operating-system 2、Current version&#xff1a;Nessus-5.2.4-debian6_i386.deb 3、Install&#xff1a;dpkg -i Nessus-5.2.4-debian6_i386.deb # dpkg -i Nessus-5.2.4-debian6_i386.deb Selecting p…

面試官問:JS的繼承

原文作者若川&#xff0c;掘金鏈接&#xff1a;https://juejin.im/post/5c433e216fb9a049c15f841b寫于2019年2月20日&#xff0c;現在發到公眾號聲明原創&#xff0c;之前被《前端大全》公眾號等轉載閱讀量超1w&#xff0c;知乎掘金等累計閱讀量超過1w。導讀&#xff1a;文章主…

qt 快速按行讀取文件_這是知識點之Linux下分割文件并保留文件頭

點擊上方"開發者的花花世界"&#xff0c;選擇"設為星標"技術干貨不定時送達&#xff01;這是一個知識點方便快捷的給結構化數據文件分割大小并保留文件的表頭&#xff0c;幾十個G的結構化文件不僅閱讀編輯麻煩&#xff0c;而且使用受限&#xff0c;因此高效…

mono 調用windows webService

1. 實現linux mono Develop中調用windows 中的webService l linux 與 windows 在一個局域網的網段中 l windows 的IIs中發布webService 2. windows 中的設置 l webService 的代碼 using System; using System.Collections.Generic; using System.Linq; using S…

Linux 內存機制

轉載鏈接&#xff1a;http://blog.csdn.net/tianlesoftware/article/details/5463790 一. 內存使用說明 Free 命令相對于top 提供了更簡潔的查看系統內存使用情況&#xff1a; [rootrac1 ~]# free total used free shared buffers cached Mem: …

network中的請求信息,headers中的每一項分別是什么意義?

這里是修真院前端小課堂&#xff0c;每篇分享文從 【背景介紹】【知識剖析】【常見問題】【解決方案】【編碼實戰】【擴展思考】【更多討論】【參考文獻】 八個方面深度解析前端知識/技能&#xff0c;本篇分享的是&#xff1a; 【network中的請求信息&#xff0c;headers中的每…

學習 sentry 源碼整體架構,打造屬于自己的前端異常監控SDK

前言這是學習源碼整體架構第四篇。整體架構這詞語好像有點大&#xff0c;姑且就算是源碼整體結構吧&#xff0c;主要就是學習是代碼整體結構&#xff0c;不深究其他不是主線的具體函數的實現。文章學習的是打包整合后的代碼&#xff0c;不是實際倉庫中的拆分的代碼。其余三篇分…

巴西龜吃什么

1、活蝦&#xff0c;哈哈&#xff0c;巴西龜最喜歡的食物&#xff0c;超市很多雞尾蝦買的&#xff0c;就那種&#xff0c;要活的&#xff0c;鍛煉它們的天性&#xff0c;一次一只可以吃一、兩天&#xff1b; 2、蚶子&#xff0c;貝殼類&#xff0c;活的&#xff0c;整個扔進去&…

綁定dictionary 給定關鍵字不再字典中_VBA代碼集錦-利用字典做兩列數據的對比并對齊...

源數據&#xff1a;代碼&#xff1a;Sub 對比()Dim arr, brr, crrDim i, j, n, lastrowA, lastrowB As Integer建立字典對象Set d CreateObject("scripting.dictionary")獲取數據區域最后一行的行數lastrowA Sheets("對比對齊兩列數據").Cells(Rows.Coun…

linux啟動時掛載rootfs的幾種方式 .

轉載鏈接&#xff1a;http://blog.csdn.net/zuokong/article/details/9022707 根文件系統&#xff08;在樣例錯誤消息中名為 rootfs&#xff09;是 Linux 的最基本的組件。根文件系統包含支持完整的 Linux 系統所需的所有內容。它包含所有應用程序、配置、設備、數據等 Linux 中…

PHP 手冊

by:Mehdi AchourFriedhelm BetzAntony DovgalNuno LopesHannes MagnussonGeorg RichterDamien SeguyJakub Vrana其他貢獻者2018-06-19Edited By: Peter Cowburn中文翻譯人員&#xff1a;肖盛文洪建家穆少磊宋琪黃嘯宇王遠之肖理達喬楚戴劼褚兆瑋周夢康袁玉強段小強© 1997-…

前端使用puppeteer 爬蟲生成《React.js 小書》PDF并合并

前端也可以爬蟲&#xff0c;寫于2018年08月29日&#xff0c;現在發布到微信公眾號申明原創。掘金若川 本文章鏈接&#xff1a;https://juejin.im/post/5b86732451882542af1c80821、 puppeteer 是什么&#xff1f;puppeteer: Google 官方出品的 headless Chrome node 庫puppetee…

蜘蛛與佛的故事

最近閉關,空面四壁,窗外層巒疊嶂,窗臺上只有一盆花每日陪著我&#xff0c;朋友們都說我要成佛了,想想也是&#xff01; 于是在閉關即將結束的時候找了一篇佛的故事送給自己&#xff0c;希望自己能夠頓悟一些"禪"機。 從前&#xff0c;有一座圓音寺&#xff0c;每天都…

信息安全管理與評估_計算機工程學院教師參加“信息安全管理與評估賽項”說明會...

看了就要關注我&#xff0c;喵嗚~2019年3月15日下午&#xff0c;2019年陜西省高等職業院校技能大賽“信息安全管理與評估賽項說明會”在咸陽職業技術學院舉行。出席本次會儀的有咸陽職業技術學院教務處長楊新宇、神州數碼范永強經理、神州數碼信息安全工程師高峰和各院校指導教…

haproxy概念和負載均衡

https://pan.baidu.com/s/1Sq2aJ35zrW2Xn7Th9j7oOA //軟件百度網盤連接 在80.100虛擬機上 systemctl stop firewalld //關閉防火墻 setenforce 0 //關閉監控 yum install lrz* -y //安裝上傳軟件 tar xf haproxy-1.5.15.tar.gz -C /opt/ //解壓壓縮包到/opt/ cd /op…

PHP用戶注冊郵箱驗證激活帳號

轉載鏈接&#xff1a;http://www.helloweba.com/view-blog-228.html 本文將結合實例&#xff0c;講解如何使用PHPMysql完成注冊帳號、發送激活郵件、驗證激活帳號、處理URL鏈接過期的功能。 業務流程 1、用戶提交注冊信息。 2、寫入數據庫&#xff0c;此時帳號狀態未激活。 …

知乎問答:一年內的前端看不懂前端框架源碼怎么辦?

知乎問答&#xff1a;一年內的前端看不懂前端框架源碼怎么辦&#xff1f;以下是我的回答&#xff0c;閱讀量 1000。現在轉載到微信公眾號中。鏈接&#xff1a;https://www.zhihu.com/question/350289336/answer/910970733其他回答的已經很好了。剛好最近在寫學習源碼整體架構系…

幫自己發個求職簡歷

幫自己發個求職簡歷 發個求職信息。本人擅長Web開發&#xff0c;尤其擅長Flex&#xff0c;愿從事Web開發&#xff0c;最好是Web前端開發&#xff0c;下面是我的詳細個人簡歷&#xff1a; 個人信息&#xff1a; 姓名&#xff1a;伍國耀 年齡&#xff1a;23 性別&#xff1a;男 專…

python函數 global_**Python的函數參數傳遞 和 global

函數的參數到底是傳遞的一份復制的值&#xff0c;還是對內存的引用&#xff1f;我們看下面一段代碼&#xff1a;a []def fun(x):x.append(1)fun(a)print(a)想想一下&#xff1a;如果傳遞的是一份復制的值&#xff0c;那么列表a應該是不會變化的&#xff0c;還是空列表&#xf…