Foreach-Object vs Foreach循环的运行时

Ben*_*rup 3 powershell

我想做我的脚本的进度条,但后来我需要总量的文件夹.

是否存在显着的运行时差异:

Get-ChildItem $path -Directory | ForEach-Object {
    #do work
}
Run Code Online (Sandbox Code Playgroud)

$folders = Get-ChildItem $path -Directory
foreach($folder in $folders){
    #do work
}
Run Code Online (Sandbox Code Playgroud)

然后我可以$folders.Count用作我的文件夹总数.我不知道如何使用foreach-object循环来完成它.

Ans*_*ers 5

是的,存在性能差异.foreach比这更快ForEach-Object但需要更多内存,因为所有items($folders)必须在内存中.ForEach-Object当它们通过管道时,一次处理一个项目,因此它具有较小的内存占用,但速度不够快foreach.

另见.


Avs*_*lom 5

您可以自行检查:

Measure-Command {
    1..100000 | ForEach-Object $_
}

1.17s

Measure-Command {
    foreach ($i in 1..100000)
    {
    $i
    }
}

0.15s
Run Code Online (Sandbox Code Playgroud)

  • 没关系,重点是显示两个选项之间的速度比较,反正你可以做`$Dirs = Get-ChildItem $path -Directory` 然后`$Dirs | Foreach-Object 或 foreach ($d in $Dirs) {}` (2认同)

wOx*_*xOm 5

管道设计用于在项目出现时立即对其进行处理,因此在管道传输时不知道列表的整个长度。

Get-ChildItem $path -Directory | ForEach {
    # PROCESSING STARTS IMMEDIATELY
    # LENGTH IS NOT KNOWN
}
Run Code Online (Sandbox Code Playgroud)
  • 优点:处理立即开始,没有延迟建立列表。
  • 缺点:列表长度在完全处理之前是未知的

另一方面,将列表分配给一个变量此时会构建整个列表,如果列表包含大量项目或构建速度很慢,例如,如果它是一个包含很多项目的目录,这可能会花费非常多的时间嵌套子目录或慢速网络目录。

# BUILD THE ENTIRE LIST AND ASSIGN IT TO A VARIABLE
$folders = Get-ChildItem $path -Directory
# A FEW MOMENTS/SECONDS/MINUTES/HOURS LATER WE CAN PROCESS IT
ForEach ($folder in $folders) {
    # LENGTH IS KNOWN: $folders.count
}
Run Code Online (Sandbox Code Playgroud)
  • 构建列表+ForEach语句的优点:整体花费的时间更少,因为处理{ }块不是在每个项目上调用的,而通过管道,它像函数或脚本块一样被调用,并且在PowerShell中这种调用开销非常大。
  • 缺点:列表赋值语句的初始延迟可能非常大