Настройка науки
Сначала несколько скриптов, которые помогут нам проверить это. Это создает 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и содержимое, похоже, что вы набрали функции на консоли, так что нет ресурсов для проверки.