前回の記事で、Write-Ouputを計測するときにちょっと困りました。
PowerShellでSubstitute(変数代入)、Host(ホスト出力)、Content(ファイル出力)するコストのベンチマーク
Write-Outputは状況に応じて、「Objectをパイプに渡す」か「Host画面に出力」するか自動的に切り替えます。 その切り替える要素は、ScriptBlockとしてパイプされる、プロパティを指定されるなどなわけですが……Measure-Commandを使うとObjectとして出力/計測されてしまうわけです。
これでは、Measure-Commandで実行時間の計測ができません。
ということで、今回は、System.Diagnostics.StopWatchを使ったオレオレMeasure-Stopwatchのご紹介です。
ソース全文
サクッとFunction化してあるので利用しやすいかと。
function Measure-Stopwatch{ [CmdletBinding()] param( [parameter(Mandatory=$true)] [ScriptBlock]$Command, [switch]$Days, [switch]$Hours, [switch]$Minutes, [switch]$Seconds, [switch]$Milliseconds ) function Start-InputScriptBlock { $sw = New-Object System.Diagnostics.StopWatch # Start Stopwatch $sw.Start() #TargetCommand to measure $command.Invoke() # Stop Stopwatch $sw.Stop() #Show Result switch ($true){ $Days {$sw.Elapsed.TotalDays} $Hours {$sw.Elapsed.TotalHours} $Minutes {$sw.Elapsed.TotalMinutes} $Seconds {$sw.Elapsed.TotalSeconds} $Milliseconds {$sw.Elapsed.TotalMilliseconds} default {$sw.Elapsed} } #Reset Result $sw.Reset() } Start-InputScriptBlock }
利用例1 : ホスト出力時間も加味する
本コマンドレットは、Measure-Commandではできないホスト出力コスト計測もできます。 それには、スイッチやプロパティを指定せずにコマンドを実行します。
なお、Get-Dateの出力がされた後に、計測時間も出力されます。そのため、所要時間は、ホスト出力分も加味されています。
#フル表記 PS> Measure-Stopwatch -Command {Get-Date} DisplayHint : DateTime Date : 2013/03/12 0:00:00 Day : 12 DayOfWeek : Tuesday DayOfYear : 71 Hour : 12 Kind : Local Millisecond : 781 Minute : 21 Month : 3 Second : 18 Ticks : 634986876787816533 TimeOfDay : 12:21:18.7816533 Year : 2013 DateTime : 2013年3月12日 12:21:18 #-Commandパラメータは省略可能 PS> Measure-Stopwatch {Get-Date} Days : 0 Hours : 0 Minutes : 0 Seconds : 0 Milliseconds : 6 Ticks : 68850 TotalDays : 7.96875E-08 TotalHours : 1.9125E-06 TotalMinutes : 0.00011475 TotalSeconds : 0.006885 TotalMilliseconds : 6.885 #好きな計測時間出力スイッチ指定 (-Days / -Hours / -Minutes / -Seconds / -Milliseconds) PS> Measure-Stopwatch -Command {Get-Date} -Milliseconds DisplayHint : DateTime Date : 2013/03/12 0:00:00 Day : 12 DayOfWeek : Tuesday DayOfYear : 71 Hour : 12 Kind : Local Millisecond : 827 Minute : 24 Month : 3 Second : 57 Ticks : 634986878978273745 TimeOfDay : 12:24:57.8273745 Year : 2013 DateTime : 2013年3月12日 12:24:57
利用例2 : ホスト出力しないコストを計測する
逆に、Measure-Commandのようにホスト出力せずにコスト計測できます。
それには、2つの方法があり、いずれもMeasure-Commandと同等の計測時間が得られます。
#プロパティを指定 PS> (Measure-Stopwatch -Command {Get-Date}).TotalMilliseconds 0.2406 #Select-Object -Last 1 で出力結果のみ取得する PS> (Measure-Stopwatch -Command {Get-Date}).TotalMilliseconds Days : 0 Hours : 0 Minutes : 0 Seconds : 0 Milliseconds : 0 Ticks : 3401 TotalDays : 3.93634259259259E-09 TotalHours : 9.44722222222222E-08 TotalMinutes : 5.66833333333333E-06 TotalSeconds : 0.0003401 TotalMilliseconds : 0.3401
参考までに、Measure-Commandの結果です。
PS> (Measure-Command {Get-Date}).TotalMilliseconds 0.2953 PS> Measure-Command {Get-Date} Days : 0 Hours : 0 Minutes : 0 Seconds : 0 Milliseconds : 0 Ticks : 3149 TotalDays : 3.64467592592593E-09 TotalHours : 8.74722222222222E-08 TotalMinutes : 5.24833333333333E-06 TotalSeconds : 0.0003149 TotalMilliseconds : 0.3149
まとめ
このMeasure-Stopwatchを利用することで、Write-Outputのホスト出力も計測可能になります。
PS> Measure-Stopwatch -Command {Write-Output $hoge} PS> Measure-Stopwatch -Command {Write-Output $hoge} | Select -Last 1