powershell-4.0 - Invoke-Command 比命令本身更快?

标签 powershell-4.0 invoke-command

我试图衡量一些在 PowerShell 中写入文件的方法。毫无疑问,但我不明白为什么第一个 Measure-Command下面的语句比第二条语句需要更长的时间来执行。

它们是相同的,但在第二个中我写了一个脚本块发送到 Invoke-Command在第一个我只运行命令。

关于Invoke-Command的所有信息我能找到的速度是关于远程处理的。

此块大约需要 4 秒:

Measure-Command {
    $stream = [System.IO.StreamWriter] "$PSScriptRoot\t.txt"
    $i = 0
    while ($i -le 1000000) {
        $stream.WriteLine("This is the line number: $i")
        $i++
    }
    $stream.Close() 
} # takes 4 sec

下面这段代码完全相同,但写在传递给 Invoke-Command 的脚本块中大约需要 1 秒:

Measure-Command {
    $cmdtest = {
        $stream = [System.IO.StreamWriter] "$PSScriptRoot\t2.txt"
        $i = 0
        while ($i -le 1000000) {
            $stream.WriteLine("This is the line number: $i")
            $i++
        }
        $stream.Close()
     }
     Invoke-Command -ScriptBlock $cmdtest
} # Takes 1 second

这怎么可能?

最佳答案

事实证明,基于 PowerShell 团队成员在 this related GitHub issue 上的反馈。 , 该问题更普遍地与(隐式)点采购有关 (比如直接调用一个表达式)vs. 在子作用域中运行 ,例如 & ,调用运算符,或者,在手头的情况下,使用 Invoke-Command -ScriptBlock .
在子作用域中运行可避免在(隐式)点源时执行的变量查找。
因此,从 Windows PowerShell v5.1/PowerShell Core 6.2 开始,您可以通过简单地通过 & { ... } 调用它们来加速无副作用的表达式。 , 在子作用域中(有点违反直觉,因为创建新作用域需要额外的工作):
也就是说,此优化可用于不希望(直接)修改调用者变量的表达式。
以下简化代码,使用 foreach循环 100 万次的表达式 ( 1e6 ) 证明了这一点:

# REGULAR, direct invocation of an expression (a `foreach` statement in this case), 
# which is implicitly DOT-SOURCED
(Measure-Command { $result = foreach ($n in 1..1e6) { $n } }).TotalSeconds

# OPTIMIZED invocation in CHILD SCOPE, using & { ... }
# 10+ TIMES FASTER.
(Measure-Command { $result = & { foreach ($n in 1..1e6) { $n } } }).TotalSeconds

关于powershell-4.0 - Invoke-Command 比命令本身更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42138296/

相关文章:

powershell - 计数不适用于 -include jpg

powershell - 从 powershell 检查 azure 资源是否具有有效名称

PowerShell - 将属性名称从 Pascal 大小写转换为带下划线的大写

powershell - 如何使用 PowerShell 检查 csv 列中的空行

powershell-4.0 - PowerShell 中分隔线的重复字符

windows - 尽管是管理员,但对 localhost 的访问被拒绝 - PowerShell

powershell - 如何将参数列表中的类对象传递到另一台计算机并在其上调用函数?

powershell - 如何将ScriptStackTrace保留在远程计算机上的Invoke-Command中引发的异常中?

powershell - 使用脚本中的参数调用第二个脚本