文字列を実行可能なコードに変換するソリューションを探しています。私のコードは極端に遅く、4.7 seconds
で実行されます。これを行うより速い方法がありますか?文字列を実行可能なコードのパフォーマンスに変換する
文字列: "* 5"
出力:25
コード:まあ
class Program {
static void Main(string[] args) {
var value = "5 * 5";
Stopwatch sw = new Stopwatch();
sw.Start();
var test = Execute(value);
sw.Stop();
Debug.WriteLine($"Execute string at: {sw.Elapsed}");
}
private static object Execute(string content) {
var codeProvider = new CSharpCodeProvider();
var compilerParameters = new CompilerParameters {
GenerateExecutable = false,
GenerateInMemory = true
};
compilerParameters.ReferencedAssemblies.Add("system.dll");
string sourceCode = CreateExecuteMethodTemplate(content);
CompilerResults compilerResults = codeProvider.CompileAssemblyFromSource(compilerParameters, sourceCode);
Assembly assembly = compilerResults.CompiledAssembly;
Type type = assembly.GetType("Lab.Cal");
MethodInfo methodInfo = type.GetMethod("Execute");
return methodInfo.Invoke(null, null);
}
private static string CreateExecuteMethodTemplate(string content) {
var builder = new StringBuilder();
builder.Append("using System;");
builder.Append("\r\nnamespace Lab");
builder.Append("\r\n{");
builder.Append("\r\npublic sealed class Cal");
builder.Append("\r\n{");
builder.Append("\r\npublic static object Execute()");
builder.Append("\r\n{");
builder.AppendFormat("\r\nreturn {0};", content);
builder.Append("\r\n}");
builder.Append("\r\n}");
builder.Append("\r\n}");
return builder.ToString();
}
}
あなたは*実行コードではないことに注意してください。文字列を作成してからMSILにコンパイルし、次にJITtedを取得し、* then *実際に実行します。実際のパフォーマンスを測定する場合は、ベンチマークの外でコンパイルされたメソッドを作成します。ベンチマークを開始する前に 'RuntimeHelpers.PrepareDelegate'をJITに呼び出すこともできます。そして、平均時間を得るためにそれを連続して百万回呼び出す。 – Groo
あなたはこのスレッドを見ましたか? http://stackoverflow.com/questions/234217/is-it-possible-to-compile-and-execute-new-code-at-runtime-in-net これは重複しているわけではありませんが、試してベンチマークするための良い代替アプローチをいくつか教えてください。 – zoubida13
コンパイルは、コードを複数回実行する場合(つまり、複数回呼び出す場合やループがあるため)にのみ意味があります。コードを一度呼び出すとコードにループがない場合、コンパイルよりも解釈が速くなります。 – dasblinkenlight