回答:
私が知っている4つのオプションのいくつかのテストを行いました。
Measure-Command {$(1..1000) | Out-Null}
TotalMilliseconds : 76.211
Measure-Command {[Void]$(1..1000)}
TotalMilliseconds : 0.217
Measure-Command {$(1..1000) > $null}
TotalMilliseconds : 0.2478
Measure-Command {$null = $(1..1000)}
TotalMilliseconds : 0.2122
## Control, times vary from 0.21 to 0.24
Measure-Command {$(1..1000)}
TotalMilliseconds : 0.2141
だから私はあなたがOut-Null
オーバーヘッドのため以外のものを使用することをお勧めします。次に重要なのは、読みやすさです。私はリダイレクトし$null
て$null
自分と同じに設定するのが好きです。以前はにキャストすることを好んで使用して[Void]
いましたが、コードを一瞥したときや新しいユーザーにとってはそれほど理解しにくいかもしれません。
私は出力をにリダイレクトすることをわずかに好むと思い$null
ます。
Do-Something > $null
編集する
stejのコメントが再度出た後、出力を破棄するオーバーヘッドをより適切に分離するために、パイプラインを使用してさらにいくつかのテストを行うことにしました。
以下は、単純な1000オブジェクトパイプラインを使用したいくつかのテストです。
## Control Pipeline
Measure-Command {$(1..1000) | ?{$_ -is [int]}}
TotalMilliseconds : 119.3823
## Out-Null
Measure-Command {$(1..1000) | ?{$_ -is [int]} | Out-Null}
TotalMilliseconds : 190.2193
## Redirect to $null
Measure-Command {$(1..1000) | ?{$_ -is [int]} > $null}
TotalMilliseconds : 119.7923
この場合、にOut-Null
は約60%のオーバーヘッドがあり、> $null
約0.3%のオーバーヘッドがあります。
補遺2017-10-16:パラメータのOut-Null
使用という別のオプションを見落としました-inputObject
。これを使用するとオーバーヘッドがなくなるように見えますが、構文は異なります。
Out-Null -inputObject ($(1..1000) | ?{$_ -is [int]})
次に、単純な100オブジェクトパイプラインを使用したいくつかのテストについて説明します。
## Control Pipeline
Measure-Command {$(1..100) | ?{$_ -is [int]}}
TotalMilliseconds : 12.3566
## Out-Null
Measure-Command {$(1..100) | ?{$_ -is [int]} | Out-Null}
TotalMilliseconds : 19.7357
## Redirect to $null
Measure-Command {$(1..1000) | ?{$_ -is [int]} > $null}
TotalMilliseconds : 12.8527
ここでもOut-Null
、約60%のオーバーヘッドがあります。一方> $null
、オーバーヘッドは約4%です。ここでの数値は、テストごとに少し異なります(私はそれぞれ約5回実行して、中間点を選びました)。でも、使わない理由は明らかだと思いますOut-Null
。
Out-Null
多分オーバーヘッドです。しかし、1つのオブジェクトをOut-Null
0.076ミリ秒にパイプ処理する場合、imhoはスクリプト言語としては依然として完全に
私はこれが古いスレッドであることを理解していますが、@ JasonMArcherの上記の回答を実際に受けている人にとって、何年も前から修正されていないことに驚いています。実際には、パイプラインが遅延を追加しているのかどうかは関係ありません。 Out-Nullかどうか。実際、以下のテストを実行すると、[void]および$ void =への同じ「より高速な」キャストが、何年もの間ずっと高速であると考えていたが、実際には低速であり、実際には非常に低速であることがすぐにわかります。パイプラインを追加します。つまり、何かにパイプするとすぐに、out-nullを使用しないというルール全体がゴミ箱に入ります。
下のリストの最後の3つのテストの証明。恐ろしいOut-nullは32339.3792ミリ秒でしたが、待ってください-[void]へのキャストはどれだけ速くなりましたか?34121.9251 ms?!?WTF?これらは私のシステム上のREAL#であり、VOIDへのキャストは実際には遅くなりました。= $ nullはどうですか?34217.685ms .....それでもゆっくりと遅い したがって、最後の3つの簡単なテストが示すように、パイプラインが既に使用されている場合、多くの場合、Out-Nullは実際には高速です。
それで、これはなぜですか?シンプル。Out-Nullへのパイプが遅かったのは100%幻覚でした。ただし、PIPING TO ANYTHINGの方が低速であり、基本的なロジックでそれを知っているのではないでしょうか。速度が遅いことを知らないだけかもしれませんが、これらのテストは、パイプラインを使用するコストを回避できる場合は、そのコストについてのストーリーを確実に伝えます。また、アウトヌルが悪である実際のシナリオは非常に少ないため、100%間違っているわけではありません。いつ?Out-Nullを追加すると、パイプラインアクティビティのみが追加されます。言い換えれば... $(1..1000)のような単純なコマンドの理由| 上記のOut-Nullはtrueを示しました。
上記のすべてのテストにOut-Stringにパイプを追加するだけで、#は根本的に変化し(または単に下記のものを貼り付け)、実際にわかるように、多くの場合、Out-Nullは実際より高速になります。
$GetProcess = Get-Process
# Batch 1 - Test 1
(Measure-Command {
for ($i = 1; $i -lt 99; $i++)
{
$GetProcess | Out-Null
}
}).TotalMilliseconds
# Batch 1 - Test 2
(Measure-Command {
for ($i = 1; $i -lt 99; $i++)
{
[void]($GetProcess)
}
}).TotalMilliseconds
# Batch 1 - Test 3
(Measure-Command {
for ($i = 1; $i -lt 99; $i++)
{
$null = $GetProcess
}
}).TotalMilliseconds
# Batch 2 - Test 1
(Measure-Command {
for ($i = 1; $i -lt 99; $i++)
{
$GetProcess | Select-Object -Property ProcessName | Out-Null
}
}).TotalMilliseconds
# Batch 2 - Test 2
(Measure-Command {
for ($i = 1; $i -lt 99; $i++)
{
[void]($GetProcess | Select-Object -Property ProcessName )
}
}).TotalMilliseconds
# Batch 2 - Test 3
(Measure-Command {
for ($i = 1; $i -lt 99; $i++)
{
$null = $GetProcess | Select-Object -Property ProcessName
}
}).TotalMilliseconds
# Batch 3 - Test 1
(Measure-Command {
for ($i = 1; $i -lt 99; $i++)
{
$GetProcess | Select-Object -Property Handles, NPM, PM, WS, VM, CPU, Id, SI, Name | Out-Null
}
}).TotalMilliseconds
# Batch 3 - Test 2
(Measure-Command {
for ($i = 1; $i -lt 99; $i++)
{
[void]($GetProcess | Select-Object -Property Handles, NPM, PM, WS, VM, CPU, Id, SI, Name )
}
}).TotalMilliseconds
# Batch 3 - Test 3
(Measure-Command {
for ($i = 1; $i -lt 99; $i++)
{
$null = $GetProcess | Select-Object -Property Handles, NPM, PM, WS, VM, CPU, Id, SI, Name
}
}).TotalMilliseconds
# Batch 4 - Test 1
(Measure-Command {
for ($i = 1; $i -lt 99; $i++)
{
$GetProcess | Out-String | Out-Null
}
}).TotalMilliseconds
# Batch 4 - Test 2
(Measure-Command {
for ($i = 1; $i -lt 99; $i++)
{
[void]($GetProcess | Out-String )
}
}).TotalMilliseconds
# Batch 4 - Test 3
(Measure-Command {
for ($i = 1; $i -lt 99; $i++)
{
$null = $GetProcess | Out-String
}
}).TotalMilliseconds
Out-Null
パイプラインを使用するように強制することは何もありません。そのため、パイプラインのオーバーヘッドを示す最善の方法は、パイプラインのOut-Null
有無にかかわらず呼び出すことです。私のシステムでは、10,000回の反復で、0.576秒とOut-Null -InputObject $GetProcess
5.656秒(ほぼ10倍遅い)が得られ$GetProcess | Out-Null
ます。
[void]
、$null
それでもより優れてい| Out-Null
ます。これはパイプラインが原因で発生し、後のバッチでデルタが縮小することがわかりますが、私のマシンでOut-Null
はどのバッチでも高速に実行されません。
[void]
そして- $null
よりも優れ| Out-Null
てい|
ます。Out-Null -InputObject (expression)
比較してみてください。
Out-Null
たとえば、パイプラインで使用できるコマンドレットもありますAdd-Item | Out-Null
。
NAME
Out-Null
SYNOPSIS
Deletes output instead of sending it to the console.
SYNTAX
Out-Null [-inputObject <psobject>] [<CommonParameters>]
DETAILED DESCRIPTION
The Out-Null cmdlet sends output to NULL, in effect, deleting it.
RELATED LINKS
Out-Printer
Out-Host
Out-File
Out-String
Out-Default
REMARKS
For more information, type: "get-help Out-Null -detailed".
For technical information, type: "get-help Out-Null -full".
[void]
Out-Nullソリューションの方が「パワーシェルっぽい」ように見えても、私は切り替えると思います。
[void]
は非常に明確に見えます(私が言ったようにpowershellishではありません)。行の先頭に、この行に出力がないことがわかります。したがって、これは別の利点であり、大きなループでOut-Nullを実行すると、パフォーマンスが問題になる可能性があります;)
個人的には、... | Out-Null
他のユーザーがコメントしているように、... > $null
およびと比較して「PowerShellish」のアプローチのように見えるため、これを使用してい[void] ...
ます。 $null = ...
は特定の自動変数を利用しており、見過ごされがちですが、他のメソッドでは、追加の構文を使用して、式の出力を破棄することを明確にしています。ので... | Out-Null
と... > $null
、式の終わりに来る私は、彼らが効果的に「我々はこれまでに行ってきたすべてのものを取って、それを捨てる」、プラスあなたは(例えばデバッグ目的のために簡単にそれらをコメントアウトすることができます通信すると思います... # | Out-Null
)、パッティングに比べ$null =
あるいは[void]
前実行後に何が起こるかを決定する式。
ただし、別のベンチマークを見てみましょう。各オプションの実行にかかる時間ではなく、各オプションの機能を理解するのにかかる時間です。PowerShellやスクリプト作成の経験がまったくない同僚との環境で働いていたため、自分が見ている言語を理解できなくても、数年後にやって来る誰かが彼らがそれをサポートまたは交換しなければならない立場にあるかもしれないので、それが何をしているのかを理解するチャンスと戦う。これは、今まで他の方法よりも1つの方法を使用する理由としては一度も発生していませんが、その位置にいて、help
コマンドまたはお気に入りの検索エンジンを使用して、Out-Null
します。すぐに役立つ結果が得られますよね?次に、[void]
およびで同じことを実行してください$null =
。それほど簡単ではありませんか?
確かに、値の出力を抑制することは、スクリプトの全体的なロジックを理解するのに比べるとかなり細かい部分であり、適切なコードを書く能力をトレードオフする前に、コードをそんなに「弱める」ことができます初心者の読む能力...あまり良くないコード。私のポイントである、それはPowerShellで堪能な人もが持つさえ慣れていない可能性があります[void]
、$null =
など、及びそれらがより速く実行するか、型に少ないキーストロークがかかる場合がありますという理由だけで、彼らが行うための最善の方法だという意味ではありませんあなたがやろうとしていること、そして言語が風変わりな構文を与えるからといって、より明確でよく知られているものの代わりにそれを使用するべきだという意味ではありません。*
*私はそれOut-Null
が明確でよく知られていると思いますが、私にはわかりません$true
。どちらのオプションあなたは感じているが、私はあなたが使用を推奨していますオプションですが、関係なく、タイム・ツー・タイプまたは時間に実行する、(自分を含む)、将来のリーダーとあなたのコードの編集者がアクセス可能な明確な、最もです。