2016-09-22 27 views
1

我想要做一個腳本的進度條,但後來我需要一定量的文件夾。Foreach-Object與Foreach循環的運行時間

有之間的顯著運行差異:

Get-ChildItem $path -Directory | ForEach-Object { 
    #do work 
} 

$folders = Get-ChildItem $path -Directory 
foreach($folder in $folders){ 
    #do work 
} 

那麼我可以用$folders.Count作爲我的文件夾的總量。我不知道如何用foreach對象循環來做到這一點。

+0

'我不知道如何與一個foreach對象做loop.'不可能通過設計。 – wOxxOm

+0

@wOxxOm確定這是可能的。你只需要在'ForEach-Object'中增加一個計數器:'$ i = 0; ... | ForEach-Object {$ i ++; ...}; $ i' –

+0

@AnsgarWiechers,在討論的上下文中沒有意義。您正在回答技術方面的問題,但忽略了在枚舉發生之前知道文件夾數目的總體目標。 – wOxxOm

回答

0

管道設計立即處理的物品,因爲他們表現得如此,而它的管道輸送列表的整個長度是不知道。

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聲明:花費總時間不因爲處理{ }塊不是在每個項目上調用而與管道調用它像一個函數或腳本塊,這個調用PowerShell中的開銷非常大。
  • 缺點:列表中的賦值語句初始延遲可能會非常巨大
3

是的,存在性能差異。 foreachForEach-Object快,但需要更多的內存,因爲所有項目($folders)都必須在內存中。 ForEach-Object在處理流水線時一次處理一個項目,所以它的內存佔用量較小,但不如foreach那麼快。

See also

2

您可以自行覈實:

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

1.17s 

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

0.15s 
+0

但是你不包括Get-ChildItem部分。首先,我將不得不獲取所有文件夾,然後循環而不是循環瀏覽文件夾。 –

+0

沒關係,關鍵是要顯示兩個選項之間的速度比較,無論如何你可以做'$ Dirs = Get-ChildItem $ path -Directory'然後'$ Dirs | Foreach-Object或foreach($ dirs中的$ dirs){}' – Avshalom