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