2

ac# アプリケーションに小さなスクリプトを埋め込んでいます。
パフォーマンスを向上させるために、アプリケーションの起動時にコンパイルします。

public CompiledCode CompileScript(string script)
{
    return engine.CreateScriptSourceFromString(script).Compile();
}

CompiledCode インスタンスは Dictionary に格納されるため、後で再利用できます。

それらを実行するときが来たら、次のようなものを使用します。

result = code.Execute(scope);  

scope は、ScriptScope単純なヘルパー クラスによって維持される のインスタンスです。
そのスコープは、スクリプトで使用できる変数とアセンブリが適切に追加されるように、ヘルパーのインスタンスが作成されるときに設定されます。

if (variables != null)
{
    scope = engine.CreateScope(variables);
}
else
{
    scope = engine.CreateScope();
}


if (assemblies != null)
{                
    assemblies.ForEach(a => scope.Engine.Runtime.LoadAssembly(a));
}

基本的に、アセンブリのリストがヘルパー クラスのコンストラクターに渡され、さまざまな場所でヘルパー クラスのインスタンスを再利用します。(特定のシナリオでは複数のヘルパー インスタンスが必要なので、静的クラスではありませんが、この質問のコンテキストでは、単一のインスタンスについて話しています)

これを通常の PC で使用する場合、コードのコンパイル/実行のオーバーヘッドは無視できます。
ただし、これを実行していてRaspberryPI、特定のスクリプトを初めて実行するときに非常に長い時間がかかることに気付きました。(2 行のスクリプトで最大 40 秒)

CompiledCode同じインスタンスの後続の実行は、非常に高速 (200 ミリ秒) で実行されます。

したがって、既にコンパイルされたコードがあります (奇妙なことに、最初のコンパイルも非常に高速です) が、特定のCompiledCodeインスタンスでの Execute() の最初の呼び出しには時間がかかります。

今私が疑問に思っているのは、それExecute()が初めて何をするのか、実際にコードを実行せずに以前に行っていることを実行する方法はありますか? コードのコンパイルと実際の実行の間に追加のステップがあるようです。

ヘルパークラスで定義されたスコープを再利用するという事実に関連しているのではないかと考えていました
が、もちろん、実行
時にデフォルトのスコープを使用するだけでは、変数やアセンブリ参照はありません。

アップデート:

RaspberryPI で実行するということは、Mono を使用していることを意味します。
より具体的には、Mono 2.10.8.1 (Debian 2.10.8.1-8)執筆時点で MonoGame のこの正確なバージョンでのみ動作
する非常に特定のバージョンの MonoGame に依存しているため、Mono を更新できません。

4

1 に答える 1

2

危険な推測ですが、何が起こっているのかというと、IronPython アセンブリが JIT されているということです。唯一の問題は、IronPython を呼び出す他のコード パスがあることです。Mono の JIT がアセンブリ レベルで機能するのか、型/メソッド レベルで機能するのかわかりません。IronPython および DLR アセンブリで AOT を実行してみて、それがまったく役立つかどうかを確認できます。

于 2013-03-21T19:41:31.910 に答える