为何7-Zip的-mmt搭配PowerShell的ForEach-Object -Parallel性能更优?
问题:PowerShell
ForEach-Object -Parallel 与7-Zip -mmt的性能异常关联 我使用PowerShell v7.3.7编写了遍历文件并通过7-Zip归档的脚本,遇到了以下不符合预期的性能表现:
- 仅启用7-Zip的多线程参数
-mmt时,脚本执行耗时180秒; - 搭配
ForEach-Object -Parallel且设置-ThrottleLimit 1时,耗时降至50秒; - 调整节流限制无法进一步提升性能,当数值超过逻辑核心数的50%时,执行时间反而延长;
- 禁用
-mmt(设置为-mmt=off)后,耗时又回到180秒。
原本认为7-Zip自身的多线程机制已能充分利用CPU核心,但实际情况是只有在Parallel模式下(即使限制为1线程),7-Zip才能高效利用核心。我好奇PowerShell的-Parallel参数如何影响7-Zip的-mmt功能,猜测可能与runspace的创建有关,但无法确定原因。有没有人遇到过类似情况或有相关见解?
参考脚本
param( [Parameter(Mandatory=$true)] [string]$name, [Parameter(Mandatory=$true)] [string]$password ) # The 7-Zip executable path (modify if necessary) $7zipPath = "C:\Program Files\7-Zip\7z.exe" # Ensure 7-Zip is installed if (!(Test-Path $7zipPath)) { throw "7-Zip not found at path $7zipPath" } $items = Get-ChildItem -Path .\ | Where-Object { $_.Extension -ne ".ps1" } $timer = Measure-Command { $items | ForEach-Object -Parallel { $item = $_ $name = $using:name $password = $using:password $7zipPath = $using:7zipPath $guid = [guid]::NewGuid().ToString() $zipFileWithoutPassword = "${name}_${guid}.zip" $zipFileWithPassword = "${name}${guid}.zip" # Create a non-password protected zip with no compression $argListNoPassword = "a -tzip ""$zipFileWithoutPassword"" ""$item"" -mx=0 -mmt" Start-Process -Wait -FilePath "$7zipPath" -ArgumentList $argListNoPassword -NoNewWindow # Add password protection to the zip using 7-Zip with AES256 $argListWithPassword = "a -tzip ""$zipFileWithPassword"" ""$zipFileWithoutPassword"" -p$password -mem=AES256 -mx=0 -mmt" Start-Process -Wait -FilePath "$7zipPath" -ArgumentList $argListWithPassword -NoNewWindow # Remove non-password protected zip Remove-Item -Path $zipFileWithoutPassword } -ThrottleLimit 1 } Write-Host "Total execution time: $($timer.TotalSeconds) seconds"
执行说明
将脚本保存为.ps1文件,执行时会归档当前文件夹内除.ps1外的所有文件,运行命令:
./the_script.ps1 archive-entry somepassword
内容的提问来源于stack exchange,提问作者Benny Bottema
相关产品推荐
相关产品推荐

