CompiledCode.Execute在第一次迭代期间需要很长时间

时间:2013-03-20 07:16:58

标签: c# mono ironpython

我在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的精确版本。

1 个答案:

答案 0 :(得分:2)

有一个猜测,我会说发生的事情是IronPython组件正在被JIT。唯一的问题是有其他代码路径调用IronPython,我不知道Mono的JIT是否在汇编级别或类型/方法级别上工作。您可以尝试在IronPython和DLR程序集上进行AOT,看看是否有帮助。