Digamos que você tenha um método ou cmdlet que retorne algo, mas você não deseja usá-lo e não deseja produzi-lo. Eu encontrei estas duas maneiras:
Add-Item > $null
[void]Add-Item
Add-Item | Out-Null
O que você usa? Qual é a abordagem melhor / mais limpa? Por quê?
powershell
null
void
Hinek
fonte
fonte
Respostas:
Acabei de fazer alguns testes das quatro opções que conheço.
Então, eu sugiro que você use qualquer coisa, menos
Out-Null
devido a sobrecarga. A próxima coisa importante, para mim, seria a legibilidade. Eu meio que gosto de redirecionar$null
e definir igual a$null
mim mesmo. Eu prefiro[Void]
transmitir a transmissão , mas isso pode não ser tão compreensível quando se olha para o código ou para novos usuários.Acho que prefiro redirecionar a saída para
$null
.Editar
Após o comentário de stej novamente, decidi fazer mais alguns testes com pipelines para isolar melhor a sobrecarga de descartar a saída.
Aqui estão alguns testes com um pipeline simples de 1000 objetos.
Nesse caso,
Out-Null
possui uma sobrecarga de cerca de 60% e uma sobrecarga de> $null
cerca de 0,3%.Adendo 16-10-2017: Eu originalmente ignorei outra opção com
Out-Null
o uso do-inputObject
parâmetro. Usando isso, a sobrecarga parece desaparecer, no entanto, a sintaxe é diferente:E agora, para alguns testes com um pipeline simples de 100 objetos.
Aqui, novamente,
Out-Null
há cerca de 60% de sobrecarga. Enquanto> $null
tem uma sobrecarga de cerca de 4%. Os números aqui variaram um pouco de teste para teste (eu corri cada cinco vezes e escolhi o meio termo). Mas acho que mostra um motivo claro para não usarOut-Null
.fonte
Out-Null
é talvez sobrecarga. Mas .. se tubulação um objeto paraOut-Null
0,076 milissegundos, IMHO ainda é perfeitamente bem para linguagem de script :)Sei que esse é um tópico antigo, mas, para aqueles que consideram a resposta aceita pelo @ JasonMArcher acima como um fato, estou surpreso que isso não tenha sido corrigido. Muitos de nós sabemos há anos que é o PIPELINE que adiciona o atraso e nada a ver com a questão de saber se é Out-Null ou não. De fato, se você executar os testes abaixo, verá rapidamente que o mesmo elenco "mais rápido" para [void] e $ void = que, durante anos, todos nós pensamos que era mais rápido, na verdade são MUITO LENTO e de fato MUITO LENTO quando você adiciona QUALQUER canalização. Em outras palavras, assim que você direciona para qualquer coisa, toda a regra de não usar nulo fora entra no lixo.
Prova, os últimos 3 testes na lista abaixo. O horrível nulo Out foi 32339,3792 milissegundos, mas espere - quanto mais rápido o lançamento foi para [void]? 34121.9251 ms?!? WTF? Estes são REAIS no meu sistema, a transmissão para VOID foi mais lenta. Que tal = $ null? 34217.685ms ..... ainda friggin MAIS LENTO! Portanto, como mostram os três últimos testes simples, o Out-Null é realmente MAIS RÁPIDO em muitos casos quando o pipeline já está em uso.
Então, por que isso? Simples. É e sempre foi 100% uma alucinação que a tubulação para Out-Null fosse mais lenta. É, no entanto, que TUBAR PARA QUALQUER COISA é mais lento, e nós já não sabíamos disso através da lógica básica? Podemos simplesmente não saber QUANTO MAIS LENTO, mas esses testes certamente contam uma história sobre o custo do uso do pipeline, se você puder evitá-lo. E, na verdade, não estávamos 100% errados, porque há um número muito PEQUENO de cenários verdadeiros em que nulo externo é ruim. Quando? Ao adicionar Out-Null, adicione a atividade do pipeline ONLY. Em outras palavras ... o motivo de um comando simples como $ (1..1000) | Out-Null como mostrado acima mostrou verdadeiro.
Se você simplesmente adicionar um pipe adicional ao Out-String em todos os testes acima, os #s mudam radicalmente (ou apenas cola os abaixo) e, como você pode ver por si mesmo, o Out-Null se torna MAIS RÁPIDO em muitos casos:
fonte
Out-Null
um pipeline; portanto, a melhor maneira de mostrar a sobrecarga de um pipeline é invocá-loOut-Null
com e sem ele. No meu sistema, para 10.000 iterações, recebo 0,576 segundosOut-Null -InputObject $GetProcess
contra 5,656 segundos (quase 10 vezes mais lento) por$GetProcess | Out-Null
.[void]
e$null
ainda obtive um desempenho melhor que| Out-Null
. Entendo que isso se deve ao pipeline e o delta diminui com os lotes posteriores, mas na minha máquinaOut-Null
não há um desempenho mais rápido em nenhum dos lotes.[void]
e$null
terá um desempenho melhor do que| Out-Null
- por causa do|
. TenteOut-Null -InputObject (expression)
para comparação.Há também o
Out-Null
cmdlet, que você pode usar em um pipeline, por exemploAdd-Item | Out-Null
.Página de manual para Out-Null
fonte
[void]
mesmo que a solução Out-Null pareça mais "powerhellish".[void]
parece muito claro (embora não seja tão potente quanto eu disse), você verá no início da linha que não há saída nessa linha. Portanto, esta é outra vantagem, e se você fizer um Out-Null em grande loop, o desempenho poderia ser um problema;)Eu consideraria usar algo como:
A saída de
$a.Add
não é retornada - isso vale para todas as$a.Add
chamadas de método. Caso contrário, você precisará[void]
pré- anexar antes de cada chamada.Em casos simples, eu concordaria
[void]$a.Add
porque é bastante claro que a saída não será usada e será descartada.fonte
Pessoalmente, uso
... | Out-Null
porque, como outros comentaram, essa parece ser a abordagem mais "PowerShellish" em comparação com... > $null
e[void] ...
.$null = ...
está explorando uma variável automática específica e pode ser fácil ignorar, enquanto os outros métodos tornam óbvio com sintaxe adicional que você pretende descartar a saída de uma expressão. Porque... | Out-Null
e... > $null
no final da expressão, acho que eles se comunicam efetivamente "pegue tudo o que fizemos até esse ponto e jogue fora", além de poder comentá-los com mais facilidade para fins de depuração (por exemplo... # | Out-Null
), em comparação com colocar$null =
ou[void]
antes a expressão para determinar o que acontece após a execução.Porém, vejamos uma referência diferente: não a quantidade de tempo que leva para executar cada opção, mas a quantidade de tempo que leva para descobrir o que cada opção faz . Tendo trabalhado em ambientes com colegas que não tinham experiência com o PowerShell ou mesmo com scripts, eu costumo tentar escrever meus scripts de uma maneira que alguém que, anos depois, talvez nem entenda o idioma que está procurando, possa ter um chance de descobrir o que está fazendo, pois eles podem estar em uma posição de precisar apoiá-lo ou substituí-lo. Isso nunca me ocorreu como uma razão para usar um método sobre os outros até agora, mas imagine que você está nessa posição e usa o
help
comando ou seu mecanismo de pesquisa favorito para tentar descobrir o queOut-Null
faz. Você obtém um resultado útil imediatamente, certo? Agora tente fazer o mesmo com[void]
e$null =
. Não é tão fácil, não é?É verdade que suprimir a saída de um valor é um detalhe bem menor comparado à compreensão da lógica geral de um script, e você só pode tentar "emburrecer" seu código muito antes de trocar sua capacidade de escrever um bom código para um script. capacidade do novato de ler ... código não tão bom. Meu argumento é que é possível que alguns que são fluentes no PowerShell nem estejam familiarizados com
[void]
,$null =
etc., e apenas porque eles podem ser executados mais rapidamente ou levar menos pressionamentos de tecla para digitar, não significa que sejam a melhor maneira de fazer isso. o que você está tentando fazer, e apenas porque uma linguagem fornece uma sintaxe peculiar, não significa que você deve usá-la em vez de algo mais claro e mais conhecido. ** Presumo que isso
Out-Null
seja claro e conhecido, o que não sei ser$true
. Qualquer opção que você achar mais clara e acessível aos futuros leitores e editores do seu código (inclusive você), independentemente do tempo de digitação ou de execução, é a opção que recomendo que você use.fonte