Настройка науки
Сначала несколько скриптов, которые помогут нам проверить это. Это создает 2000 файлов сценариев, каждый из которых имеет одну маленькую функцию:
1..2000 | % { "Function Test$_(`$someArg) { Return `$someArg * $_ }" > "test$_.ps1" }
Этого должно быть достаточно, чтобы обычные издержки запуска не имели большого значения. Вы можете добавить больше, если хотите. Это загружает их все, используя точечный источник:
dir test*.ps1 | % {. $_.FullName}
Это загружает их всех, сначала читая их содержимое:
dir test*.ps1 | % {iex (gc $_.FullName -Raw)}
Теперь нам нужно провести серьезную проверку работы PowerShell. Мне нравится JetBrains dotPeek для декомпилятора. Если вы когда-либо пытались встроить PowerShell в приложение .NET , вы обнаружите, что сборка, которая включает в себя большинство соответствующих материалов, является System.Management.Automation
. Декомпилируйте это в проект и PDB.
Чтобы увидеть, где проводится все это таинственное время, мы будем использовать профилировщик. Мне нравится тот, который встроен в Visual Studio. Это очень просто в использовании . Добавьте папку, содержащую PDB, в расположение символов . Теперь мы можем выполнить профилирование экземпляра PowerShell, который просто запускает один из тестовых сценариев. (Установите параметры командной строки для использования -File
с полным путем первого сценария, который нужно попробовать. Установите место запуска для папки, содержащей все крошечные сценарии.) Как только это будет сделано, откройте Свойства в powershell.exe
записи в разделе Цели и измените аргументы для использования другого скрипта. Затем щелкните правой кнопкой мыши самый верхний элемент в Performance Explorer и выберите Start Profiling., Профилировщик снова запускается с использованием другого сценария. Теперь мы можем сравнить. Убедитесь, что вы нажали «Показать весь код», если вы выбрали эту опцию; для меня это отображается в области уведомлений в сводном представлении примера отчета о профилировании.
Результаты приходят в
На моей машине Get-Content
версия заняла 9 секунд, чтобы просмотреть файлы сценариев 2000 года. Важными функциями на «Горячем пути» были:
Microsoft.PowerShell.Commands.GetContentCommand.ProcessRecord
Microsoft.PowerShell.Commands.InvokeExpressionCommand.ProcessRecord
Это имеет большой смысл: нам нужно ждать, Get-Content
чтобы прочитать контент с диска, и нам нужно ждать, Invoke-Expression
чтобы использовать это содержимое.
В версии с точечным источником моя машина потратила чуть более 15 секунд на обработку этих файлов. На этот раз функции на Hot Path были нативными методами:
WinVerifyTrust
CodeAuthzFullyQualifyFilename
Второй из них, по-видимому, недокументирован, но WinVerifyTrust
«выполняет действие проверки доверия с указанным объектом». Это настолько неопределенно, насколько это возможно, но, другими словами, эта функция проверяет подлинность данного ресурса с помощью данного поставщика. Обратите внимание, что я не включил какие-либо необычные средства безопасности для PowerShell, и моя политика выполнения сценариев такова Unrestricted
.
Что это значит
Короче говоря, вы ожидаете, что каждый файл будет каким-то образом проверен, возможно, проверен на подпись, хотя это не является необходимым, если вы не ограничиваете скрипты, которые разрешено запускать. Когда вы, gc
а затем iex
и содержимое, похоже, что вы набрали функции на консоли, так что нет ресурсов для проверки.