反射是一項很有趣的技術,她提供了另乙個視角來模糊、統一地看待我們用**搭建起來的小世界。由於之前工作的關係,小魚醬曾用c++初略地實現過一套反射系統,用來支援遊戲中屬性編輯器的開發,在c++中反射是一項注入式或者後生成的一種程式設計方式,會導致**難以閱讀,脫離語言的美感。但在c#中的反射卻是自然而優雅。因為最近在做手遊開發的緣故,開始研究unity3d,開始重拾久違的c#。於是下面小魚醬將簡單介紹一下c#中的反射技術,並通過函式呼叫的角度來比較一下各個方式的效能。
c#通過system.reflection程式集提供出了強大完整的反射功能,使我們可以在程式執行期獲得「程式集」、「模組」、「型別」等資訊,同時她也提供出了一種通用的方式的來訪問與使用這些資訊。於是我們在**的世界中,面對不同的「人」或「物」,就有了不卑不亢的同一種腔調。在這裡我們只討論函式呼叫,後面也只以函式呼叫的角度來比較一下各個反射機制的效能。
在原生反射的框架下進行函式呼叫有兩種較為常用的「招式」。分別如下:
1. 通過methodinfo
以函式方法物件抽象呼叫函式,呼叫效率較低。
2. 通過assembly/// /// 原生反射測試
///
public class nativereflecttest
;//極大次數呼叫測試執行時間
profiler.start();
for (int i = 0; i < 1000000; i++)
profiler.stopandprint("1000000 times invoked by reflection: ");}}
用assembly生成直接的物件,然後呼叫期則等同於直接呼叫函式。
/// /// 程式集測試
///
public class assemblytest
profiler.stopandprint("1000000 times invoked by assembly: ");}}
其實**本身與反射沒有什麼直接的關係,只是因為我們討論的是函式呼叫,而委託天生就流著函式呼叫的血脈。相對於原生反射,委託顯得更加特例化一些,他需要為每種不同的形式的函式預先定義出委託的型別,然後可以在不同的類的函式上進行繫結。委託比原生反射的抽象抽象程度弱化了一些。
繫結委託的「招式」如下:
public delegate void sayhandle(ref string word, int count);
/// /// **測試
///
public class delegatetest
profiler.stopandprint("1000000 times invoked by delegate: ");}}
在codeproject 上介紹了一種fastinvoke方法來進行函式反射。相對於原生反射,她提供了一種更底層的方式來實現。主要是msil語言來建立指令流,以達到呼叫期與平常**相同的執行效率。msil語言被稱為microsoft中間語言,主要用來做跨平台支援,c#將msil**生成到當前機器的機器碼。在fastinvoke中,直接生成呼叫函式的msil**,則可以等同於編寫c#直接呼叫函式的**。
在小魚醬包裝後的介面中,fastinvoke方法的「招式」如下:
/// /// 快速呼叫測試
///
public class fastinvoketest
;//極大次數呼叫測試執行時間
profiler.start();
for (int i = 0; i < 1000000; i++)
profiler.stopandprint("1000000 times invoked by fastinvoke: ");}}
下面是幾種反射呼叫的乙個實驗,分別呼叫乙個簡單函式極大次數(一百萬次),如下:效能結果:class program
}
結論為,原生呼叫的時間消耗與直接呼叫相比較差別巨大;而assembly需要先通過反射構建出物件,然後再通過直接呼叫的方式訪問函式,構建物件的效能效率沒有統計,如果加入統計過程中,assembly方法的效能會比原生呼叫還要低,同時assembly方法破壞了反射需要的統一抽象。delegate方法其實就是直接呼叫,但是與assembly相同的是他同樣也破壞了反射需要的統一抽象。而fastinvoke與直接呼叫效能相差不多,並且保持了統一形式進行訪問的特性。
c 中的反射機制
反射的概述 反射的定義 審查元資料並收集關於它的型別資訊的能力。元資料 編譯以後的最基本資料單元 就是一大堆的表,當編譯程式集或者模組時,編譯器會建立乙個類定義表,乙個字段定義表,和乙個方法定義表等。system.reflection命名空間包含的幾個類,允許你反射 解析 這些元資料表的 syste...
c 中的反射機制
反射的概述 反射的定義 審查元資料並收集關於它的型別資訊的能力。元資料 編譯以後的最基本資料單元 就是一大堆的表,當編譯程式集或者模組時,編譯器會建立乙個類定義表,乙個字段定義表,和乙個方法定義表等。system.reflection命名空間包含的幾個類,允許你反射 解析 這些元資料表的 syste...
C 的反射機制
type type cassembly.assembly.gettype moduleclass object params new object 3 params 0 modulecode params 1 titlefront modulename params 2 e no igeneraht...