什么是更好(更清洁)的方式来忽略PowerShell中的输出?
假设你有一个方法或一个CMDlet返回一些东西,但是你不想使用它,你不想输出它。 我发现了这两种方式:
Add-Item > $null [void]Add-Item Add-Item | Out-Null
你用什么? 哪个更好/更干净的方法? 为什么?
我只是对我所了解的四个选项做了一些testing。
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
所以我build议你使用任何东西,除了Out-Null
由于开销。 对我而言,下一个重要的事情就是可读性。 我有点像redirect到$null
和设置等于$null
我自己。 我使用更喜欢铸造[Void]
,但是这可能不是可以理解的,当看到代码或新用户。
我想我稍微偏好redirect输出到$null
。
Do-Something > $null
编辑
在stej再次发表评论之后,我决定用pipe道做更多的testing,以更好地隔离垃圾输出的开销。
以下是一些简单的1000对象stream水线的testing。
## 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:我最初忽略了使用-inputObject
参数的Out-Null
另一个选项。 使用这个开销似乎消失,但是语法是不同的:
Out-Null -inputObject ($(1..1000) | ?{$_ -is [int]})
现在用一个简单的100对象pipe道进行一些testing。
## 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%。 这里的数字从testing到testing都有所不同(我跑了5次左右,select了中间的地方)。 但是我认为这显示了不使用Out-Null
的明确理由。
还有Out-Null
cmdlet,您可以在pipe道中使用它,例如Add-Item | Out-Null
Add-Item | Out-Null
。
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".
我会考虑使用像这样的东西:
function GetList { . { $a = new-object Collections.ArrayList $a.Add(5) $a.Add('next 5') } | Out-Null $a } $x = GetList
$a.Add
输出不会被返回 – 这对所有的$a.Add
方法调用都适用。 否则,您需要在每次通话之前预先[void]
。
在简单情况下,我会去[void]$a.Add
因为它非常清楚输出不会被使用,并被丢弃。
我意识到这是一个古老的线索,但对于那些拿@ Jason先生接受的答案上面的事实,我很惊讶它没有得到纠正我们很多人已经知道了多年,这实际上是PIPELINE加延迟和没有任何关系这是否是否定的。 事实上,如果你运行下面的testing,你会很快看到,相同的“更快”的转换为[void]和$ void =多年来,我们都认为这是更快,实际上是非常慢,实际上非常慢你添加任何stream水线任何东西。 换句话说,只要你pipe到任何东西,不使用out-null的整个规则进入垃圾。
certificate,在下面的列表中的最后3个testing。 可怕的Out-null是32339.3792毫秒,但是等一下 – 投射到[void]要快多less? 34121.9251毫秒?!? WTF? 这些是我的系统上的REAL#,投到VOID实际上是SLOWER。 怎么样= $ null? 34217.685ms …..仍然是下降! 所以,最后三个简单的testing显示,在pipe道已经被使用的情况下,在很多情况下Out-Null实际上是更快的。
那么,为什么呢? 简单。 对于Out-Null而言,一直是100%的幻觉。 然而,pipe道任务是慢的,我们不是已经知道,通过基本逻辑? 我们可能不知道多less速度,但是这些testing确实讲述了使用pipe道的成本,如果可以避免的话。 而且,我们并不是真正的100%错误,因为有一小部分真正的场景,out-null是邪恶的。 什么时候? 添加Out-Null时添加ONLYpipe道活动。 换句话说….一个简单的命令像$(1..1000)|的原因 如上所示的Out-Null显示为真。
如果你只是在上面的每个testing中添加一个额外的pipe道,那么#就会根本改变(或者只是粘贴下面的那个),正如你自己看到的,在很多情况下,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