Просто слово о том, как сделать (неправильные) выводы из любой из команд измерения производительности, указанных в ответах. Существует ряд ловушек, которые следует принимать во внимание, помимо рассмотрения времени простейшего вызова (пользовательской) функции или команды.
Sjoemelsoftware
«Sjoemelsoftware» проголосовало за голландское слово 2015 года «
Sjoemelen» означает «обман», а слово « sjoemelsoftware» появилось в связи со скандалом с выбросами Volkswagen. Официальное определение - «программное обеспечение, используемое для влияния на результаты испытаний».
Лично я считаю, что « Sjoemelsoftware » не всегда намеренно создается для того, чтобы обманывать результаты тестов, но может возникать в результате практической ситуации, которая похожа на тестовые примеры, показанные ниже.
В качестве примера, используя перечисленные команды измерения производительности, Language Integrated Query (LINQ) (1) , часто квалифицируется как на голодном способ получить что - то сделать , и это часто бывает, но , конечно , не всегда! Любой, кто измеряет увеличение скорости в 40 или более раз по сравнению с собственными командами PowerShell, вероятно, неправильно измеряет или делает неправильный вывод.
Дело в том, что некоторые классы .Net (например, LINQ) используют ленивую оценку (также называемую отложенным выполнением (2) ). Это означает, что когда вы присваиваете выражение переменной, оно почти сразу кажется выполненным, но на самом деле оно еще ничего не обрабатывает!
Предположим, что у вас есть точечный источник вашей . .\Dosomething.ps1
команды, которая имеет либо PowerShell, либо более сложное выражение Linq (для простоты объяснения я непосредственно встроил выражения непосредственно в Measure-Command
):
$Data = @(1..100000).ForEach{[PSCustomObject]@{Index=$_;Property=(Get-Random)}}
(Measure-Command {
$PowerShell = $Data.Where{$_.Index -eq 12345}
}).totalmilliseconds
864.5237
(Measure-Command {
$Linq = [Linq.Enumerable]::Where($Data, [Func[object,bool]] { param($Item); Return $Item.Index -eq 12345})
}).totalmilliseconds
24.5949
Результат кажется очевидным, более поздняя команда Linq примерно в 40 раз быстрее, чем первая команда PowerShell . К сожалению, не все так просто ...
Давайте выведем результаты:
PS C:\> $PowerShell
Index Property
----- --------
12345 104123841
PS C:\> $Linq
Index Property
----- --------
12345 104123841
Как и ожидалось, результаты такие же, но если вы обратили пристальное внимание, вы заметите, что отображение $Linq
результатов заняло гораздо больше времени, чем $PowerShell
результаты.
Давайте определим это , просто получив свойство полученного объекта:
PS C:\> (Measure-Command {$PowerShell.Property}).totalmilliseconds
14.8798
PS C:\> (Measure-Command {$Linq.Property}).totalmilliseconds
1360.9435
Потребовалось примерно в 90 раз больше времени для извлечения свойства $Linq
объекта, чем $PowerShell
объекта, и это был всего лишь один объект!
Также обратите внимание на другую ловушку, что если вы сделаете это снова, некоторые шаги могут появиться намного быстрее, чем раньше, это потому, что некоторые выражения были кэшированы.
В итоге, если вы хотите сравнить производительность между двумя функциями, вам нужно будет реализовать их в используемом вами случае, начать с нового сеанса PowerShell и основывать свои выводы на фактической производительности полного решения.
(1) Для получения дополнительной информации и примеров по PowerShell и LINQ я рекомендую этот сайт: Высокопроизводительный PowerShell с LINQ (2) Я думаю, что между этими
двумя концепциями есть небольшое различие, так как при ленивой оценке результат вычисляется при необходимости применительно к отсроченное выполнение, в котором результат вычисляется, когда система простаивает