Powershellが遅いなら、コストのかからない方法を考えよう特集第四弾です。 PowerShellで結果がホスト表示される時にNull破棄をしたいことは多々あります。 そして、Null破棄はやり方が色々あります。 そこで、今回はNull破棄で最もコストがかからず実行速度に影響を与えない方法を考えてみます。 UserVoiceにもあったりしたり。
Null破棄をする方法
まずNull破棄をする手段を考えてみましょう。
{ScriptBlock} | Out-Null
[Void]{ScriptBlock}
{ScriptBlock} > $null
$null = {ScriptBlock}
以上の4つがぱっと思いつきます。
テストコード
では、それぞれのベンチマークを取ることでコストを考えます。 テスト1 以下のコードで1..1000を生成実行する際のベンチを10000回実行して平均を取りました。
# Null破棄しない 1..10000 | ForEach-Object{ [double](Measure-Command {$(1..1000)} | select -ExpandProperty TotalMilliseconds) } | Measure-Object -Average # | out-Null 1..10000 | ForEach-Object{ [double](Measure-Command {$(1..1000) | Out-Null} | select -ExpandProperty TotalMilliseconds) } | Measure-Object -Average # [void] 1..10000 | ForEach-Object{ [double](Measure-Command {[Void]$(1..1000)} | select -ExpandProperty TotalMilliseconds) } | Measure-Object -Average # > $null 1..10000 | ForEach-Object{ [double](Measure-Command {$(1..1000) > $null} | select -ExpandProperty TotalMilliseconds) } | Measure-Object -Average # $null = 1..10000| ForEach-Object{ [double](Measure-Command {$null = $(1..1000)} | select -ExpandProperty TotalMilliseconds) } | Measure-Object -Average
テスト2 以下のコードは、1..1000を生成し、[int]型チェックする際のベンチを10000回実行して平均を取りました。
# Null破棄しない 1..10000 | ForEach-Object{ [double](Measure-Command {$(1..1000) | where {$_ -is [int]}} | select -ExpandProperty TotalMilliseconds) } | Measure-Object -Average # | out-Null 1..10000 | ForEach-Object{ [double](Measure-Command {$(1..1000) | where {$_ -is [int] | Out-Null}} | select -ExpandProperty TotalMilliseconds) } | Measure-Object -Average # [void]は、Cast出来ないため省きます。 # > $null 1..10000 | ForEach-Object{ [double](Measure-Command {$(1..1000) | where {$_ -is [int]> $null}} | select -ExpandProperty TotalMilliseconds) } | Measure-Object -Average # $null = 1..10000| ForEach-Object{ [double](Measure-Command {$null = $(1..1000) | where {$_ -is [int]}} | select -ExpandProperty TotalMilliseconds) } | Measure-Object -Average
ベンチ結果
ベンチ結果です。
| Null Operation | Test1 | Test2 |
|---|---|---|
| None | 0.29 | 95.93 |
| Out-Null | 21.59 | 224.24 |
| [void] | 0.19 | - |
| > $null | 0.17 | 100.04 |
| $null = | 0.22 | 99.10 |
まとめ
Null破棄する際に| Out-Nullはパフォーマンスが悪いです。
パイプラインを多用しがちですが、$nullが読みやすさも良く、[void]は型変換できないパターンが多いのでAdd-Typeも悪くなく、| Out-Nullさえつかわなければ問題ないでしょう。
参考サイト
Whats the better (cleaner) way to ignore output in PowerShell