1

Reflection.Emitを使用して、数式パーサーを作成しています(例2+2)。クラスは中置式(eg 2+2)を受け取り、それを後置式(eg)に変換し、2 2 +次に別のクラスがその後置式をILにコンパイルして、を作成しDynamicMethodます。そこから、式はコンパイル時に作成されたかのように、同様の速度で評価できます。

このコンパイラは暗黙の乗算もサポートしているため、次のようにx(2 + 2)評価されます。x * (2 + 2)

現在、ユーザー定義関数(eg f(x))を実装しようとしています。上記のような暗黙の乗算とユーザー定義関数を区別しようとすると、問題が発生します。この例は、ユーザーが入力した場合、を乗算するか、引数を指定して関数を呼び出すx(5)かをどのように知ることができますか?x5x5

これを解決するために、前のケースでは、コンパイラーはifステートメントをILストリームに挿入します。関数を呼び出して、関数がの識別子で定義されているかどうかを判別しますx。存在する場合は、変数とローカルMethodInfoを介してインスタンスをスタックに挿入します。out

私の実際の質問は、コンパイル中のMethodInfo呼び出しと同等の速度でスタック上のインスタンスを使用してメソッドを実行することは可能ですか?IlGenerator.Emit(OpCodes.Call, MethodInfo)

ありがとう。

4

1 に答える 1

1

MethodInfoスタック上のインスタンスを呼び出すことができることを私が知っている唯一の方法は、そのインスタンスのInvokeメソッドを呼び出すことです。あなたはすでにこの可能性を知っていると思いますが、あなたはそれが遅すぎるかもしれないことを恐れています。試してみて、ストレスのあるパフォーマンスの時間を計ることをお勧めします。あなたはそれがあなたの目的のために十分に速いことに気付くかもしれません。

そうでない場合は、MethodInfoインスタンスを渡さないように設計を再構築する方法を検討する必要があります。たとえば、代わりに管理対象関数ポインタを渡すことができます。これらは、ldftnおよびldvirtftn命令が返すものです。次に、命令を使用してcalliそれらの1つを呼び出すことができます。クラスcalliを使用して、オペランドとして期待される「呼び出しサイトの説明」を作成する必要があります。SignatureHelper

于 2010-08-20T04:00:41.577 に答える