最近、私はこのアプローチを使用してタイプを作成するために、オーディン内部ソースの起源を確認するために、ILを勉強し始めた理由は興味がありました。
まずスローコード例:
1 クラスTestClassを 2 { 3つの パブリックTestClassを() 4 { 5 マイリスト= 新しいリスト< 整数 > (); 6 用(INT iは= 0 ; I < 100 ; I ++ ) 7 { 8 mylist.Add(I)。 9 } 10 } 11 12 公共 int型のx = 5 。 13 公共の一覧<int型 > mylistという。 14 }
1 // ないいくつかのテスト 2 int型 needCnt = 10000 ; 3 VAR preTime = EditorApplication.timeSinceStartup。 4 のための(INT iは= 0 ; I <needCnt I ++ ) 5 { 6 TestClassをT = 新しいTestClassを()。 7 } 8 VAR nowTime = EditorApplication.timeSinceStartup。 9 DEBUG.LOG(" 通常创建的时间" +(nowTime - preTime))。 10 11 VaRのタイプ= typeof演算(TestClassを)。 12 VARコンストラクタ= type.GetConstructor(Type.EmptyTypes)。 13 VaRの方法= 新しい DynamicMethod(type.FullName + " _FastCreator " 、タイプ、Type.EmptyTypes)。 14 15 のvar IL = method.GetILGenerator()。 16 17 il.Emit(OpCodes.Newobj、コンストラクタ)。 18 il.Emit(OpCodes.Ret)。 19 20 VAR fastCreator =(機能<TestClassを>)method.CreateDelegate(typeof演算(機能<TestClassを> )); 21 22は PRETime = EditorApplication.timeSinceStartup; 23である ため(INT I = 0 ; I <needCnt I ++ ) 24 { 25 VAR T = constructor.Invoke(新しい新しい オブジェクト[] {}) 26である } 27 nowtime = EditorApplication.timeSinceStartup; 28 デバッグ.logには(" 時間とコンストラクタ呼び出しない遷移が作成" +(nowtime - PRETime)); 29 30 PRETime = EditorApplication.timeSinceStartup; 31である ため(INTは iは= 0 ; I <needCnt; I ++ ) 32 { 33 TestClassをT = constructor.Invoke(新しい オブジェクト [] {})としてTestClassを。 34 } 35 nowTime = EditorApplication.timeSinceStartup。 36 DEBUG.LOG(" 构造函数呼び出し创建的时间" +(nowTime - preTime))。 37 38 preTime = EditorApplication.timeSinceStartup。 39 のための(int型私は= 0を I <needCnt; I ++) 40 { 41は、 TestClassをT = fastCreator()は、 42である } 43が nowtime = EditorApplication.timeSinceStartup; 44である DEBUG.LOG(" 時間エミットが作成" +(nowtime - PRETime))。
(ユニティ上で直接実行)、次のようにテスト結果は以下の通りでした。
結果のように見えますが、同時にILエミットとの時間を通してレベル数新直接的で、時間によって二重に遅くmethod.Invoke。
タイプ2よりも速いタイムを容易次回(推測?)、その後、委員会に製造され、新たな3を呼び出すことはできません情報だけを表示1.起動:個人の推測オーディンは、次の理由の様々なタイプを作成するには、このアプローチを選択してください。
経験した後、より追加します。。。