我在c#应用程序中嵌入了小脚本 为了提高性能,我在应用程序启动时编译它们。
public CompiledCode CompileScript(string script)
{
return engine.CreateScriptSourceFromString(script).Compile();
}
然后将CompiledCode实例存储在Dictionary中,以便稍后重用它们。
当执行它们的时候,我使用类似的东西:
result = code.Execute(scope);
范围是由简单助手类维护的ScriptScope
实例
在创建帮助程序实例时设置该范围,以便正确添加脚本可用的变量和程序集:
if (variables != null)
{
scope = engine.CreateScope(variables);
}
else
{
scope = engine.CreateScope();
}
if (assemblies != null)
{
assemblies.ForEach(a => scope.Engine.Runtime.LoadAssembly(a));
}
基本上,程序集列表被传递给helper类的构造函数,我在各个地方重用了helper类的实例。 (不是静态类,因为我确实需要针对特定场景的多个辅助实例,但在这个问题的上下文中我们讨论的是单个实例)
在普通PC上使用它时,编译/运行代码的开销是可以忽略的。
但是,我在RaspberryPI
上运行它,并注意到第一次执行特定脚本,这需要很长时间。 (2行脚本最多可容纳40秒)
相同CompiledCode
实例的后续执行执行速度非常快(200毫秒)。
所以我已经编译了代码(奇怪的是第一次编译也非常快),但在给定的CompiledCode
实例上第一次调用Execute()需要很长时间。
现在我想知道,Execute()
第一次做了什么,有没有办法在没有实际执行代码的情况下执行早期的任何操作?
在编译和实际运行代码之间似乎还有一个额外的步骤。
我在想,也许这与我重复使用的范围有关 辅助类,但当然如果我只是在执行时使用默认范围,我没有任何变量和汇编引用。
更新
在RaspberryPI上运行它意味着我正在使用Mono。
更具体地说 单声道2.10.8.1(Debian 2.10.8.1-8)我无法更新Mono,因为我依赖于 非常具体的MonoGame版本,在编写本文时仅适用于Mono的精确版本。
答案 0 :(得分:2)
有一个猜测,我会说发生的事情是IronPython组件正在被JIT。唯一的问题是有其他代码路径调用IronPython,我不知道Mono的JIT是否在汇编级别或类型/方法级别上工作。您可以尝试在IronPython和DLR程序集上进行AOT,看看是否有帮助。