Ben*_*Ben 6 invoke-command powershell-4.0
我试图测量一些在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
Run Code Online (Sandbox Code Playgroud)
并且下面的代码完全相同,但是在传递给的脚本块中写入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
Run Code Online (Sandbox Code Playgroud)
怎么可能?
事实证明,根据 PowerShell 团队成员对此相关 GitHub 问题的反馈,该问题更普遍地与(隐式)点源(例如表达式的直接调用)与在子作用域中运行有关,例如with &,调用运算符,或者,在手头的情况下, with 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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
426 次 |
| 最近记录: |