PowerShell에서 명령 실행 타이밍


217

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

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

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

time .\do_something.ps1

답변:


337

예.

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

114
또한 다음과 같은 출력을 볼 수 있습니다. Measure-Command {ps | Out-Default}. 또는 호스트에 직접 쓰는 다른 어떤 것도 유용 할 수도 있고 그렇지 않을 수도 있습니다.
JasonMArcher 5

18
나는이 솔루션을 가져 와서 다른 사람에게 유용 할 수있는 기능을 작성했습니다. gist.github.com/2206444- 예 : time { ping -n 1 google.com } -Samples 10명령 10시간 을 실행 하고 평균, 최소 및 최대 시간을 반환합니다. -SilentSTDOUT을 삼키기 위해 추가 할 수 있습니다 .
joshuapoehls

13
내가 선호하는 것은 Measure-Command의 결과를와 같은 변수에 할당하는 것 $t = Measure-Command {<<your command or code block>>}입니다. 그것을 밖으로 시도하고 다음 입력 한 $t결과와 같은,에 액세스 할 수있는 모든 속성을 볼 수있는 프롬프트에서 $t.Milliseconds, $t.TotalSeconds예를 들어, 등 그리고 우리는 우리가 원하는대로 출력에 쓸 수를Write-Host That command took $t.TotalSeconds to complete.
Baodad

사용하는 것이 더 빠릅니까? net.stopwatch 또는 measure-command 또는 두 개의 get-date vars 비교 ... (스크립트에서 영구적으로 유지하는 것이 더 효율적인 것을 의미합니까?)
Hicsy

아마도 JasonMArcher의 의견이 포함되어있을 것입니다 (따라서 전체 PowerShell 스크립트보다 더 세밀한 방식으로 사용할 수 있음)?
피터 Mortensen

183

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

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

22
Get-History | Group {$_.StartExecutionTime.Hour} | sort Count -desc시간별로 PowerShell 사용 패턴을 확인하려면 언젠가 이것을 시도 하십시오. :-)
Keith Hill

18
이 기능을 사용하여 시작했을 때 시간이 오래 걸리지 않았을 때 시간이 오래 걸리므로 Measure-Command로 감쌀 생각은 없었습니다.
Chris Magnuson

3
powershell은 때때로 굉장합니다.
ConstantineK

나는 더 다만 1 : 이상 당신을 제공 할 수 있습니다 소원
데이비드 Ferenczy Rogožan

예, 대단합니다! 나는 다음을 사용하여 하나의 라이너를 만들었습니다 :$command = Get-History -Count 1 ; "{0}" -f ($command.EndExecutionTime - $command.StartExecutionTime)
Phil

106

사용하다 Measure-Command

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

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


내 생각 Measure-Command {<your command } | Out-Host 은-Out-Host는 스크립트 블록 밖에 있습니다
Peter McEvoy

1
@Peter-블록 안에 있어야합니다. 그렇지 않으면 Measure-Command는 콘솔로 가기 전에 출력을 소비합니다.
Droj

1
그렇습니다 ...이 경우 파이프가 필요하지 않을 수도 있습니다. 그것은 다른 블록에 싸여 있지 않으면 결과를 인쇄해야합니다 ....
Droj

2
스크립팅과 호환되므로 Out-Default가 Out-Host보다 낫습니까? jsnover.com/blog/2013/12/07/write-host-considered-harmful
MarcH

1
잘 Out-Default를 시도했는데 터미널에서도 제대로 작동하므로 항상 Out-Default를 사용하지 않는 이유는 무엇입니까? (스크립트 미안으로 시도하지 않았습니다)
MarcH

18

단순

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

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

time { .\some_command }

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


1
Measure-Command명령 출력을 숨기 므로이 솔루션이 더 좋습니다.
codekaizen

이것은 명령의 출력을 존중하는 환상적인 솔루션입니다. Unix에서와 같이 간단한 명령 (예 : "time ls")에 대해 중괄호없이이를 호출 할 수도 있습니다.
Raúl Salinas-Monteagudo 19

5

유닉스 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


문제는 "PowerShell에서 명령 실행 타이밍"입니다. 유닉스를 사용한 프로세스 타이밍과는 어떤 관계가 있습니까?
Jean-Claude DeMars

5
필자가 작성한 Powershell 함수입니다 .Powershell에서 실행 시간을 Measure-Command지정할 수있는 다양한 다른 방법 중 하나 를 사용하는 대신 실행 시간을 직접 계산하는 방법을 보여줍니다 . 원래 질문을 읽으면 " timeLinux 의 명령 과 같은"작동하는 것을 요청했습니다 .
벤더 더 큰

3

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

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 }

-2

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

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) 나는과 같은 두 개념 사이에 약간의 차이가 생각 게으른 평가 결과가 계산 필요한 경우 에 나란히 놓이는로를 시스템 이 유휴 상태 일 때 결과가 계산 된 지연된 실행


이 답변의 목적은 PowerShell의 타이밍 명령 과 관련하여 사람들이 일반적인 오해에 대한 일반적인 질문을 사람들에게 추천 할 수 있도록하는 것입니다 .Powershell question-500k 객체를 반복하는 가장 빠른 방법을 찾고 있습니다. 다른 500k 객체 배열에서 일치하는 항목 찾기
iRon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.