[powershell] PowerShell에서 명령 실행 타이밍

Linux의 ‘time’명령과 같이 PowerShell에서 명령을 실행하는 간단한 방법이 있습니까?
나는 이것을 생각해 냈다.

$s=Get-Date; .\do_something.ps1 ; $e=Get-Date; ($e - $s).TotalSeconds

하지만 더 간단한 것을 원합니다

time .\do_something.ps1



답변

예.

Measure-Command { .\do_something.ps1 }

단점 중 하나 Measure-Commandstdout출력 이 없다는 것 입니다.

[@JasonMArcher 덕분에 업데이트] 호스트에 쓰는 커맨드 렛으로 커맨드 출력을 파이핑하여이를 수정할 수 있습니다. 예를 들면 Out-Default다음과 같습니다.

Measure-Command { .\do_something.ps1 | Out-Default }

출력을 보는 다른 방법은 다음 Stopwatch과 같이 .NET 클래스 를 사용하는 것입니다 .

$sw = [Diagnostics.Stopwatch]::StartNew()
.\do_something.ps1
$sw.Stop()
$sw.Elapsed


답변

또한 역사에서 마지막 명령을 취득하고 뺄 수 EndExecutionTime의에서 StartExecutionTime.

.\do_something.ps1
$command = Get-History -Count 1
$command.EndExecutionTime - $command.StartExecutionTime


답변

사용하다 Measure-Command

Measure-Command { <your command here> | Out-Host }

파이프를 Out-Host사용하면 명령의 출력을 볼 수 있습니다 Measure-Command. 그렇지 않으면에 의해 소비됩니다 .


답변

단순

function time($block) {
    $sw = [Diagnostics.Stopwatch]::StartNew()
    &$block
    $sw.Stop()
    $sw.Elapsed
}

다음으로 사용할 수 있습니다

time { .\some_command }

당신은 출력을 조정할 수 있습니다


답변

유닉스 time명령 과 비슷하게 작성한 함수는 다음과 같습니다 .

function time {
    Param(
        [Parameter(Mandatory=$true)]
        [string]$command,
        [switch]$quiet = $false
    )
    $start = Get-Date
    try {
        if ( -not $quiet ) {
            iex $command | Write-Host
        } else {
            iex $command > $null
        }
    } finally {
        $(Get-Date) - $start
    }
}

출처 : https://gist.github.com/bender-the-greatest/741f696d965ed9728dc6287bdd336874


답변

스톱워치 사용 및 경과 시간 포맷 :

Function FormatElapsedTime($ts)
{
    $elapsedTime = ""

    if ( $ts.Minutes -gt 0 )
    {
        $elapsedTime = [string]::Format( "{0:00} min. {1:00}.{2:00} sec.", $ts.Minutes, $ts.Seconds, $ts.Milliseconds / 10 );
    }
    else
    {
        $elapsedTime = [string]::Format( "{0:00}.{1:00} sec.", $ts.Seconds, $ts.Milliseconds / 10 );
    }

    if ($ts.Hours -eq 0 -and $ts.Minutes -eq 0 -and $ts.Seconds -eq 0)
    {
        $elapsedTime = [string]::Format("{0:00} ms.", $ts.Milliseconds);
    }

    if ($ts.Milliseconds -eq 0)
    {
        $elapsedTime = [string]::Format("{0} ms", $ts.TotalMilliseconds);
    }

    return $elapsedTime
}

Function StepTimeBlock($step, $block)
{
    Write-Host "`r`n*****"
    Write-Host $step
    Write-Host "`r`n*****"

    $sw = [Diagnostics.Stopwatch]::StartNew()
    &$block
    $sw.Stop()
    $time = $sw.Elapsed

    $formatTime = FormatElapsedTime $time
    Write-Host "`r`n`t=====> $step took $formatTime"
}

사용 샘플

StepTimeBlock ("Publish {0} Reports" -f $Script:ArrayReportsList.Count)  {
    $Script:ArrayReportsList | % { Publish-Report $WebServiceSSRSRDL $_ $CarpetaReports $CarpetaDataSources $Script:datasourceReport };
}

StepTimeBlock ("My Process")  {  .\do_something.ps1 }


답변

답변에 언급 된 성능 측정 명령 중 어느 것이라도 정확하지 않은 결론을 도출하는 데 도움이됩니다. (사용자 정의) 함수 또는 명령의 호출 시간을 고려하는 것 외에도 고려해야 할 많은 함정이 있습니다.

Sjoemelsoftware

‘Sjoemelsoftware’는 2015 년의 네덜란드 단어 투표
Sjoemelen의 부정 수단을, 워드 sjoemelsoftware는 폭스 바겐 배출 스캔들로 인해 들어왔다. 공식적인 정의는 “테스트 결과에 영향을주는 데 사용되는 소프트웨어”입니다.

개인적으로, ” Sjoemelsoftware “는 항상 테스트 결과를 부정하기 위해 의도적으로 생성 된 것은 아니지만 아래에 표시된 테스트 사례와 유사한 실제 상황을 수용하는 데 기인한다고 생각합니다.

예를 들어, 나열된 성능 측정 명령 인 LINQ (Language Integrated Query) (1)을 사용 하면 종종 무언가를 수행 하는 가장 빠른 방법으로 자격이 부여 되지만 항상 그렇지는 않습니다. 기본 PowerShell 명령과 비교 하여 요소 40 이상의 속도 증가를 측정하는 사람 은 아마도 잘못 측정하거나 잘못된 결론을 도출합니다.

요점은 지연 평가를 사용하는 LINQ와 같은 일부 .Net 클래스 ( 지연된 실행 (2) 라고도 함 )입니다. 변수에 표현식을 할당하면 거의 즉시 수행 된 것처럼 보이지만 실제로는 아직 아무것도 처리하지 않았습니다!

PowerShell 또는보다 정교한 Linq 표현식이있는 명령을 소스로 표시 한다고 가정합니다 . .\Dosomething.ps1(설명을 쉽게하기 위해 직접 표현식을에 삽입했습니다 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 명령은 첫 번째 PowerShell 명령 보다 약 40 배 빠릅니다 . 불행히도, 그렇게 간단 하지 않습니다

결과를 표시합시다 :

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 세션으로 시작하여 완전한 솔루션의 실제 성능에 대한 결론을 내려야합니다.

자세한 배경 및 PowerShell 및 LINQ에 예를 들어 (1), 나는 tihis 사이트 추천 LINQ와 고성능 PowerShell을
(2) 나는과 같은 두 개념 사이에 약간의 차이가 생각 게으른 평가 결과가 계산 필요한 경우 에 나란히 놓이는로를 시스템 이 유휴 상태 일 때 결과가 계산 된 지연된 실행