PowerShell: コマンドの実行時間を計測する
Windows Server World 2007年 10月号の PowerShell 特集記事の最後に、「パフォーマンスにも少し配慮する」という項があり、Get-Command を例に、パイプラインのできるだけ前の方で、処理対象のオブジェクトを絞り込むとよいでしょう、と書いています。この例で実際どのくらいの差が出るのか計測してみたいと思います。
PowerShell のコマンドレット Measure-Command で、スクリプトブロックの実行時間を計測できます。PowerShell のスクリプトだけでなく、EXE ファイルでも計測できますので、簡単なパフォーマンス測定にも利用できます。
まず、同じスクリプトブロックを10回実行し、平均実行時間を出力する関数を作ります。
function measure10 ([scriptblock]$sb) {
foreach ($i in 1..10) {
$tms += (Measure-Command $sb).TotalMilliseconds
}
$tms/10
}
では記事の例を計測してみます。とりあえずオブジェクトをすべて受け取って、パイプラインの後半でフィルタリングする方法です。
> measure10({ Get-Command | Where-Object {$_.Verb -eq "get"} | Format-Table Verb, Noun})
50.29031
50msec ほどかかっています。パイプラインの前半、すなわち Get-Command でフィルタリングした場合は
> measure10({ Get-Command -Verb "get" | Format-Table Verb, Noun})
15.72206
ということで、約 1/3 程度という結果になりました。当然といえば当然なのですが、コマンドレットの組み合わせ方で、実行時間がかなり違っています。フィルタリング前のオブジェクト数が多いほど、オブジェクトの出力に時間がかかるコマンドレットほど、この差は大きくなると思われます。