¿Cuál es la mejor manera(más limpia) de ignorar la salida en PowerShell?
null void (4)
Supongamos que tiene un método o un CMDlet que devuelve algo, pero no desea usarlo y no desea generarlo. Encontré estas dos formas:
Add-Item > $null
[void]Add-Item
Add-Item | Out-Null
¿Que usas? ¿Cuál es el enfoque mejor / más limpio? ¿Por qué?
Acabo de hacer algunas pruebas de las cuatro opciones que conozco.
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
Por lo tanto, le sugiero que use cualquier cosa excepto Out-Null
debido a la sobrecarga. La siguiente cosa importante, para mí, sería la legibilidad. Me gusta redirigir a $null
y establecer igual a $null
. Yo prefiero el casting a [Void]
, pero eso puede no ser tan comprensible al echarle un vistazo al código o a los nuevos usuarios.
Supongo que ligeramente prefiero redirigir la salida a $null
.
Do-Something > $null
Editar
Después del comentario de Stej, decidí hacer más pruebas con tuberías para aislar mejor los gastos generales de descartar la salida.
Aquí hay algunas pruebas con una simple tubería de 1000 objetos.
## 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
En este caso, Out-Null
tiene aproximadamente un 60% de gastos generales y > $null
tiene una sobrecarga de 0.3%.
Adición 2017-10-16: Originalmente pasé por alto otra opción con Out-Null
, el uso del parámetro -inputObject
. Usando esto, la sobrecarga parece desaparecer, sin embargo, la sintaxis es diferente:
Out-Null -inputObject ($(1..1000) | ?{$_ -is [int]})
Y ahora para algunas pruebas con un simple pipeline de 100 objetos.
## 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
Aquí nuevamente, Out-Null
tiene un 60% de sobrecarga. Mientras que > $null
tiene una sobrecarga de aproximadamente 4%. Los números aquí variaron un poco de prueba en prueba (corrí aproximadamente 5 veces y escogí el término medio). Pero creo que muestra una razón clara para no usar Out-Null
.
Consideraría usar algo como:
function GetList
{
. {
$a = new-object Collections.ArrayList
$a.Add(5)
$a.Add(''next 5'')
} | Out-Null
$a
}
$x = GetList
No se devuelve el resultado de $a.Add
, que se aplica a todas las llamadas al método $a.Add
. De lo contrario, necesitaría anteponer [void]
antes de cada llamada.
En casos simples, iría con [void]$a.Add
porque está bastante claro que la salida no se usará y se descarta.
Me doy cuenta de que este es un hilo viejo, pero para aquellos que toman la respuesta aceptada de JasonMArcher como un hecho, me sorprende que no se haya corregido, muchos de nosotros hemos sabido por años que en realidad es el PIPELINE añadiendo el retraso y NADA que ver con es Out-Null o no. De hecho, si ejecuta las pruebas a continuación, verá rápidamente que el mismo lanzamiento "más rápido" a [vacío] y $ vacío = eso durante años todos pensamos que era más rápido, en realidad son TAN SÓLO LENTOS y de hecho MUY LENTOS cuando usted agrega CUALQUIER canalización en absoluto. En otras palabras, tan pronto como canalices hacia algo, toda la regla de no usar out-null va a la basura.
Prueba, las últimas 3 pruebas en la lista a continuación. El horrible Out-null fue 32339.3792 milisegundos, pero espera: ¿cuánto más rápido estaba lanzando a [void]? 34121.9251 ms?!? WTF? Estos son números REALES en mi sistema, lanzando a NULO fue en realidad más LENTO. ¿Qué tal = $ null? 34217.685ms ..... todavía friggin ¡MÁS LENTO! Entonces, como muestran las últimas tres pruebas simples, Out-Null es en realidad MÁS RÁPIDO en muchos casos cuando la tubería ya está en uso.
Entonces, ¿por qué es esto? Sencillo. Es y siempre fue una alucinación al 100% que las conexiones a Out-Null fueron más lentas. Sin embargo, es que el TUBERÍAS A CUALQUIER COSA es más lento, ¿y no sabíamos que ya lo sabíamos a través de la lógica básica? Es posible que no sepamos CUANTO más lento, pero estas pruebas ciertamente cuentan una historia sobre el costo de usar la tubería si puede evitarla. Y, en realidad, no estábamos 100% equivocados porque hay un número muy pequeño de escenarios verdaderos en los que el out-null es malo. ¿Cuando? Al agregar Out-Null está agregando la ÚNICA actividad de canalización. En otras palabras ... el motivo es un comando simple como $ (1..1000) | Out-Null como se muestra arriba mostró verdadero.
Si simplemente agrega un tubo adicional a Out-String en cada prueba anterior, los #s cambian radicalmente (o simplemente pegan los que están debajo) y como puede ver por sí mismo, Out-Null se vuelve más RÁPIDO en muchos casos:
$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
También está el cmdlet Out-Null
, que puede usar en una canalización, por ejemplo, Add-Item | Out-Null
Add-Item | Out-Null
.
Página de manual para 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".