【发布时间】:2012-05-23 17:33:41
【问题描述】:
我已经阅读了几篇关于 SO 的关于编写和编译动态 C# 代码的帖子。例如,this post。我知道可以通过多种方式完成。
但是,调用代码调用程序很慢。我做了一个简单的基准测试,它比调用原生方法慢了大约 500 倍。
我想要做的是相当于加载一个 DLL 并直接(“本机”)调用它的方法之一,这将带来我想要的速度优势。
解决此问题的最简单方法是什么?将动态代码编译成dll然后加载?可以在内存中完成吗?
编辑
我不关心编译时间。仅执行。
编辑 2、3
这是我写的基准代码:
public static int Execute(int i) { return i * 2; }
private void button30_Click(object sender, EventArgs e)
{
CSharpCodeProvider foo = new CSharpCodeProvider();
var res = foo.CompileAssemblyFromSource(
new System.CodeDom.Compiler.CompilerParameters()
{
GenerateInMemory = true,
CompilerOptions = @"/optimize",
},
@"public class FooClass { public static int Execute(int i) { return i * 2; }}"
);
var type = res.CompiledAssembly.GetType("FooClass");
var obj = Activator.CreateInstance(type);
var method = type.GetMethod("Execute");
int i = 0, t1 = Environment.TickCount, t2;
//var input = new object[] { 2 };
//for (int j = 0; j < 10000000; j++)
//{
// input[0] = j;
// var output = method.Invoke(obj, input);
// i = (int)output;
//}
//t2 = Environment.TickCount;
//MessageBox.Show((t2 - t1).ToString() + Environment.NewLine + i.ToString());
t1 = Environment.TickCount;
for (int j = 0; j < 100000000; j++)
{
i = Execute(j);
}
t2 = Environment.TickCount;
MessageBox.Show("Native: " + (t2 - t1).ToString() + Environment.NewLine + i.ToString());
var func = (Func<int, int>) Delegate.CreateDelegate(typeof (Func<int, int>), method);
t1 = Environment.TickCount;
for (int j = 0; j < 100000000; j++)
{
i = func(j);
}
t2 = Environment.TickCount;
MessageBox.Show("Dynamic delegate: " + (t2 - t1).ToString() + Environment.NewLine + i.ToString());
Func<int, int> funcL = Execute;
t1 = Environment.TickCount;
for (int j = 0; j < 100000000; j++)
{
i = funcL(j);
}
t2 = Environment.TickCount;
MessageBox.Show("Delegate: " + (t2 - t1).ToString() + Environment.NewLine + i.ToString());
}
【问题讨论】:
-
你考虑编译时间了吗?你的基准看起来如何?
-
执行 C# 构建运行时并不比之前执行 C# 构建慢 500 倍。它们是相同的,但是需要考虑开销。你的基准是什么样的,你是使用 Reflection.Emit 还是一些编译器服务来编译?
-
Invoke 是什么东西很慢,这是我的问题的中心:如何以本机速度调用该方法?
-
最后一点,上面的测试,当更准确的计时,实际上慢了 1100 倍。 Marc 给出的委托解决方案比原生解决方案慢 8.4 倍。
标签: c# dynamic compiler-construction assemblies