Если вы используете потоковую передачу и конвейерную обработку, вы должны значительно уменьшить проблему с (3), потому что при потоковой передаче каждый объект передается по конвейеру, как и когда он доступен, и не занимает много памяти, и вы должныбыть в состоянии обработать миллионы файлов (хотя это займет время).
Get-ChildItem $directory -recurse | Measure-Object -property length -sum
Я не верю, что заявление @ Stej, Get-ChildItem probably reads all entries in the directory and then begins pushing them to the pipeline.
, верно.Конвейерная обработка является фундаментальной концепцией PowerShell (предоставьте поддержку командлетов, сценариев и т. Д.).Это гарантирует, что обработанные объекты передаются по конвейеру один за другим, как и когда они доступны, а также только , когда они необходимы.Get-ChildItem
не будет вести себя иначе.
Прекрасный пример этого дан в Понимание конвейера Windows PowerShell .
Цитирование изit:
Команда Out-Host -Paging - это полезный элемент конвейера, когда у вас есть длинный вывод, который вы хотите отображать медленно.Это особенно полезно, если операция очень загружает процессор.Поскольку обработка передается командлету Out-Host, когда у нее есть готовая к отображению полная страница, командлеты, предшествующие ей в операции конвейера, останавливаются до тех пор, пока не будет доступна следующая страница вывода.Это можно увидеть, если вы используете диспетчер задач Windows для мониторинга использования ЦП и памяти Windows PowerShell.
Выполните следующую команду: Get-ChildItem C:\Windows -Recurse
.Сравните использование процессора и памяти с этой командой: Get-ChildItem
C:\Windows -Recurse | Out-Host -Paging
.
Тест на использование Get-ChildItem
на c:\
(около 179516 файлов, не миллионов, но достаточно хороших):
Использование памяти после запуска $a = gci c:\ -recurse
(а затем выполнение $a.count
) было 527,332K
.
Использование памяти после запуска gci c:\ -recurse | measure-object
было 59,452K
и никогда не превышало 80,000K
.
(Память - частный рабочий набор - из TaskManager, просматривая память для процесса powershell.exe
. Первоначально это было около 22,000K
.)
Я также попробовал с двумя миллионами файлов (у меня ушлонекоторое время для их создания!)
Аналогичный эксперимент:
Использование памяти после выполнения $a = gci c:\ -recurse
(а затем выполнение $a.count
) составило 2,808,508K
.
Использование памятиво время бега gci c:\ -recurse | measure-object
был 308,060K
и никогда не поднимался выше 400,000K
.После того, как он закончил, ему пришлось сделать [GC]::Collect()
, чтобы вернуться к уровням 22,000K
.
Я все еще убежден, что Get-ChildItem
и конвейеризация могут дать вам большие улучшения памяти даже для миллионов файлов.