Apenas uma palavra sobre como tirar conclusões (incorretas) de qualquer um dos comandos de medição de desempenho mencionados nas respostas. Há várias armadilhas que devem ser levadas em consideração, além de considerar o tempo de invocação simples de uma função ou comando (personalizado).
Sjoemelsoftware
'Sjoemelsoftware' votou a palavra holandesa do ano 2015
Sjoemelen significa trapaça, e a palavra sjoemelsoftware surgiu devido ao escândalo de emissões da Volkswagen. A definição oficial é "software usado para influenciar os resultados dos testes".
Pessoalmente, acho que o " Sjoemelsoftware " nem sempre é criado deliberadamente para enganar os resultados dos testes, mas pode ter origem em acomodar situações práticas semelhantes aos casos de teste, como mostrado abaixo.
Como exemplo, usando os comandos de medição de desempenho listados, Language Integrated Query (LINQ) (1) , é frequentemente qualificado como a maneira mais rápida de fazer alguma coisa e geralmente é, mas certamente nem sempre! Quem mede um aumento de velocidade de um fator 40 ou mais em comparação com os comandos nativos do PowerShell, provavelmente está medindo incorretamente ou tirando uma conclusão incorreta.
O ponto é que algumas classes .Net (como LINQ) usando uma avaliação lenta (também chamada de execução adiada) (2) ). Isso significa que, quando atribui uma expressão a uma variável, ela quase imediatamente parece ter sido executada, mas na verdade ainda não processou nada!
Vamos supor que você pontue sua fonte. .\Dosomething.ps1
comando que possui uma expressão do PowerShell ou uma Linq mais sofisticada (para facilitar a explicação, integrei diretamente as expressões diretamente no 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
O resultado parece óbvio, o comando Linq posterior é cerca de 40 vezes mais rápido que o primeiro PowerShell comando do . Infelizmente, não é tão simples assim ...
Vamos exibir os resultados:
PS C:\> $PowerShell
Index Property
----- --------
12345 104123841
PS C:\> $Linq
Index Property
----- --------
12345 104123841
Como esperado, os resultados são os mesmos, mas se você prestar muita atenção, perceberá que demorou muito mais tempo para exibir os $Linq
resultados do que os $PowerShell
resultados.
Vamos medir especificamente isso apenas recuperando uma propriedade do objeto resultante:
PS C:\> (Measure-Command {$PowerShell.Property}).totalmilliseconds
14.8798
PS C:\> (Measure-Command {$Linq.Property}).totalmilliseconds
1360.9435
Demorou cerca de um fator 90 a mais para recuperar uma propriedade do $Linq
objeto que o $PowerShell
objeto e esse era apenas um único objeto!
Observe também uma outra armadilha: se você fizer isso de novo, algumas etapas podem parecer muito mais rápidas do que antes, isso ocorre porque algumas das expressões foram armazenadas em cache.
Resumindo, se você deseja comparar o desempenho entre duas funções, será necessário implementá-las no seu caso usado, comece com uma nova sessão do PowerShell e baseie sua conclusão no desempenho real da solução completa.
(1) Para obter mais informações e exemplos sobre o PowerShell e o LINQ, recomendo este site: PowerShell de alto desempenho com o LINQ
(2) Acho que há uma pequena diferença entre os dois conceitos, pois na avaliação lenta, o resultado é calculado quando necessário , ao contrário de execução adiada onde o resultado é calculado quando o sistema está ocioso