powershell null void

¿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".