Лише слово про виведення (неправильних) висновків із будь-якої команди вимірювання продуктивності, згаданої у відповідях. Існує ряд підводних каменів, які слід врахувати, окрім огляду часу голого виклику (спеціальної) функції чи команди.
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) Я думаю, що між двома поняттями є незначна різниця, оскільки при ледачій оцінці результат розраховується при необхідності при призначенні відкладене виконання , якщо результат обчислюється, коли система не працює