ホームページ  >  記事  >  バックエンド開発  >  直接呼び出しと反射呼び出しの例のチュートリアル

直接呼び出しと反射呼び出しの例のチュートリアル

零下一度
零下一度オリジナル
2017-06-23 15:01:001719ブラウズ

リフレクションを使用するとパフォーマンスに問題が生じると多くの人が言います。以下でそれをテストしてみましょう。

直接呼び出しと反射呼び出し

直接呼び出しと反射呼び出しのパフォーマンスの違いを検証するデモを書いてみましょう。コードは次のとおりです:

 1 namespace ConsoleApplication7 2 { 3     class Program 4     { 5         static void Main(string[] args) 6         { 7             //比较直接调用和反射调用的性能差异 8             //7ms vs 365ms 9             int times = 1000000;10             var program = new Program();11             CodeTimerHelper.Initialize();12 13             CodeTimerHelper.Time("直接调用", times, () =>14             {15                 program.Call();16             });17 18             var t = typeof(Program);19             var obj = Activator.CreateInstance(t);20             CodeTimerHelper.Time("反射调用", times, () =>21             {22                 t.InvokeMember("Call", BindingFlags.InvokeMethod, null, obj, null);23             });24 25             Console.ReadKey();26         }27 28         /// <summary>29         /// 测试方法30         /// </summary>31         public void Call()32         {33         }34 35     }36 }

テスト結果:

100万回の呼び出しから。結果は、多くの人が言っているように、この 2 つのパフォーマンスには桁違いの違いがあることを示しています。

なぜリフレクションでパフォーマンスの損失があるのですか

リフレクションのパフォーマンスの損失があるので、具体的な損失はどこでしょうか?

1. リフレクションはアセンブリとメタデータに基づいて行われます。リフレクションを使用する場合、メタデータは文字列に基づいて検索されるため、この一連の操作はパフォーマンスに影響します。

2. 大量のボックス化とボックス化解除もパフォーマンスに影響します。ターゲットの型が分からず、メソッドに渡されるパラメータは通常オブジェクト型であるため、ボックス化とボックス化解除が大量に発生します。

リフレクション パフォーマンス最適化ソリューション

リフレクションの使用にはパフォーマンスの問題があることはすでにわかっていますが、一部のシナリオではリフレクション テクノロジを使用する必要があるため、リフレクション パフォーマンスを最適化する方法を見つける必要があります。

ここでは、Lao Zhao によって公開されている System.Linq.Expressions.Expression 式ツリー クラスを引用し、それを直接呼び出しと比較します。コードは次のとおりです。

おお、同じ 100 万回の呼び出しでも、DynamicMethodExecutor を使用した呼び出しのパフォーマンスは直接呼び出しのパフォーマンスとほぼ同じです。
DynamicMethodExecutor のカプセル化コードを添付します:

1 //3,基于表达式树2 var methodInfo = t.GetMethod("Call");3 var executor = new DynamicMethodExecutor(methodInfo);4 CodeTimerHelper.Time("Dynamic executor", times, () =>5 {6     executor.Execute(obj, null);7 });

linq の式ツリーを使用して Delegate を生成する方法に加えて、CodeDom などのコードを生成して動的にコンパイルする方法や、Emit を使用してコードを生成する方法もあります。 Reflection のパフォーマンスを向上させるには IL を直接記述する必要がありますが、比較的に上記の方法が最も簡単です。

これでリフレクション全体のまとめは完了です!

参考記事

メソッドの直接呼び出し、リフレクション呼び出し、そして…ラムダ式呼び出し

C#基礎知識復習シリーズ15:リフレクション

2.リフレクションはリフレクション、リフレクションでできること

以上が直接呼び出しと反射呼び出しの例のチュートリアルの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。