[英]Parallel.Foreach vs Foreach for data migration process
我有一個車輛清單。對於每輛車,我都在做一些遷移工作。
foreach (vehicles)
{
1 : Do database table migration for that vehicle
2 : Call an API and save them to database
}
為了提高性能,我將其並行化為:
Parallel.Foreach(vehicles)
{
--same
}
這是正確的方法嗎? 因為我的理解是,它將為每個請求的車輛創建一個新線程,因此一切應該很快運行。
進行並行TASK會大大改善嗎?
保持最大數量的並行性好嗎? 如果是,該如何決定?
如果您在每個Vehicle
項目之間幾乎沒有依賴關系,則這是正確的方法。 換句話說,您(理想情況下)不應在對每輛Vehicle
執行的Action
主體中具有任何lock
(或其他同步原語)。 但是,如果您的代碼中確實有lock
,則它們應該位於比其余方法執行速度明顯快的一部分代碼上:
Parallel.ForEach(vehicles, v => { // Some code that takes long to execute lock(_syncRoot) { _totalProcessedVehicles ++; } })
Parallel.Foreach
不會為每個Vehicle
實例創建一個線程-它會產生多個線程,並將為每個線程分配您的集合中的一部分進行處理。 線程數取決於您的硬件和可用資源。
不, Parallel.Foreach
在內部使用Task
,這樣做會加重您的代碼負擔。 同樣,使用與上述相同的邏輯在不同的線程上調度和執行任務:每個線程處理Task
的大塊。
我不建議指定最大並行度-讓CLR
為您做到; 在大多數情況下,它將做得很好。 但是,如果你想限制並行度,對過載Parallel.Foreach
它接受類型的參數ParallelOptions
。 使用屬性MaxDegreeOfParallelism
限制並行度。
方法是可以的,只需確保函數1和2是線程安全的(不要共享公共資源或至少同步它們的用法)
可能取決於瓶頸是什么,例如,如果您只有一個CPU,而您的問題是CPU,則瓶頸並行化將不會給您帶來任何好處。 如果您有多個內核(CPU),而不是CPU受限的問題,那么並行化將非常有益。 在您的情況下,限制還可能是您要將數據遷移到的數據庫,將其泛洪甚至會使情況變得更糟。
再次取決於您的瓶頸,如果它是CPU並行化程度高於CPU內核數量的並行化將不會給您帶來任何好處,相反會減慢它的速度,因為線程切換會消耗資源。 根據經驗,我主要針對CPU受限的問題選擇核心數-1,這樣系統的其余部分仍然可以響應。
對於foreach循環內的較小甚至是簡單的工作負載,初始化Parallel.Foreach的開銷也可能會吃掉它的好處。
通常,嘗試一下並視情況決定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.