PowerShell 是否编译脚本?

Does PowerShell compile scripts?

假设我有一个简单的 PowerShell 脚本:

1..3 | Write-Host 

PowerShell V2 及更早版本从未编译过脚本,它始终通过解析树中的虚拟 "eval" 方法进行解释。

PowerShell V3 及更高版本编译解析树(AST) to a LINQ expression tree, which is then compiled to a bytecode,然后解释。

如果脚本执行16次,脚本在后台JIT-编译,一旦JIT编译完成,解释后的代码将不会被使用。同样适用于循环:如果一个循环迭代16次,循环体将被JIT编译,并且循环体将在尽可能早的时间从解释转换为JIT编译。

许多操作(如访问成员或调用 C# 方法)始终在小型动态方法中进行 JIT 编译。这些动态站点针对 PowerShell 的动态特性进行了优化,以适应不同类型的按需输入。

JIT 编译代码托管在 "anonymous methods" 程序集中,无法保存。用WinDbg, you could disassemble the IL生成的代码。

将编译后的 IL 代码保存为 DLL 不太可能,因为生成的代码依赖于活动对象。从技术上讲,PowerShell 可以生成可以保存为 DLL 的代码,但尚未实现。

脚本和 REPL(交互式命令提示符)的工作方式完全相同。

请注意,如果 PowerShell 确实生成了程序集,它仍然需要安装编译脚本的 PowerShell 版本,您无法生成完全可移植的 exe。

从其他语言调用 PowerShell 脚本会有些困难和笨拙,因为有几个因素 - 主要是流水线和参数绑定 - 与普通方法调度有些不同。

您可以在 C# 中使用从 PowerShell 脚本返回的对象。从 V3 开始,如果您在 C# 中使用 dynamic 关键字,您可以在 PSObject 实例上访问属性、调用脚本方法等,就像在任何其他对象上一样。在 V3 之前,您必须使用像 psobj.Properties['SomeProperty'].

这样的 API