我想要对我的脚本执行一个进度条,但后来我需要一定数量的文件夹。
之间是否存在显着的运行时差异:
Get-ChildItem $path -Directory | ForEach-Object {
#do work
}
和
$folders = Get-ChildItem $path -Directory
foreach($folder in $folders){
#do work
}
然后我可以使用$folders.Count
作为我的文件夹总数。我不知道如何使用foreach-object循环。
答案 0 :(得分:5)
是的,存在性能差异。 foreach
比ForEach-Object
快,但需要更多内存,因为所有项目($folders
)都必须在内存中。 ForEach-Object
在通过管道时一次处理一个项目,因此它的内存占用量较小,但不如foreach
快。
答案 1 :(得分:3)
您可以自己检查:
Measure-Command {
1..100000 | ForEach-Object $_
}
1.17s
Measure-Command {
foreach ($i in (1..100000))
{
$i
}
}
0.15s
答案 2 :(得分:2)
管道设计用于在物品出现时立即处理物品,因此在管道输送时,列表的整个长度都是未知的。
Get-ChildItem $path -Directory | ForEach {
# PROCESSING STARTS IMMEDIATELY
# LENGTH IS NOT KNOWN
}
另一方面,将列表分配给变量会在此时构建整个列表,如果列表包含大量项目或构建速度很慢,则可能需要花费大量时间,例如,如果它是一个包含许多嵌套子目录或慢速网络目录的目录。
# 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
}
ForEach
语句的优点:花费的总时间较少,因为在每个项目上处理{ }
块不是调用而使用管道调用它就像一个函数或scriptblock,这种调用开销在PowerShell中非常大。