Załóżmy, że masz metodę lub polecenie cmdlet, które coś zwraca, ale nie chcesz go używać i nie chcesz tego wyprowadzać. Znalazłem te dwa sposoby:
Add-Item > $null
[void]Add-Item
Add-Item | Out-Null
Czego używasz? Jakie jest lepsze / czystsze podejście? Czemu?
powershell
null
void
Hinek
źródło
źródło
Odpowiedzi:
Właśnie przeprowadziłem testy czterech opcji, o których wiem.
Więc sugerowałbym, abyś używał czegokolwiek, ale z
Out-Null
powodu kosztów ogólnych. Następną ważną rzeczą byłaby dla mnie czytelność. Lubię przekierowywać do siebie$null
i stawiać$null
sobie równe . Wolę rzucać[Void]
, ale może to nie być tak zrozumiałe, gdy patrzę na kod lub dla nowych użytkowników.Wydaje mi się, że wolę przekierowywać wyjście do
$null
.Edytować
Po ponownym komentarzu steja postanowiłem przeprowadzić więcej testów z potokami, aby lepiej odizolować obciążenie związane z usuwaniem danych wyjściowych.
Oto kilka testów z prostym potokiem obiektów 1000.
W tym przypadku
Out-Null
ma około 60% narzut i> $null
około 0,3% narzut.Dodatek 2017-10-16: Pierwotnie przeoczyłem inną opcję z
Out-Null
użyciem-inputObject
parametru. Korzystając z tego, narzut wydaje się znikać, jednak składnia jest inna:A teraz kilka testów z prostym potokiem 100 obiektów.
Tutaj znowu
Out-Null
ma około 60% narzutu. Chociaż> $null
ma narzut około 4%. Liczby tutaj różniły się nieco od testu do testu (przebiegłem każdy z nich około 5 razy i wybrałem środek). Ale myślę, że to pokazuje jasny powód, aby nie używaćOut-Null
.źródło
Out-Null
może być nad głową. Ale ... jeśli potokujesz jeden obiekt doOut-Null
0,076 milisekundy, imho, to nadal jest w porządku dla języka skryptowego :)Zdaję sobie sprawę, że jest to stary wątek, ale dla tych, którzy przyjmują powyższą odpowiedź @ JasonMArchera za fakt, jestem zaskoczony, że nie została poprawiona, wielu z nas wiedziało od lat, że jest to tak naprawdę PIPELINE dodający opóźnienie i NIC w jest Out-Null czy nie. W rzeczywistości, jeśli uruchomisz poniższe testy, szybko zobaczysz, że te same „szybsze” rzucanie do [void] i $ void = które przez lata myśleliśmy, że było szybsze, są właściwie TAKIE WOLNE, a tak naprawdę BARDZO WOLNE, gdy dodasz JAKIEKOLWIEK rurociągi. Innymi słowy, gdy tylko do czegokolwiek potokujesz, cała zasada nieużywania out-null trafia do kosza.
Dowód, ostatnie 3 testy z poniższej listy. Straszna wartość Out-null wynosiła 32339,3792 milisekund, ale czekaj - o ile szybsze było rzucanie do [void]? 34121,9251 ms?!? WTF? To są PRAWDZIWE # w moim systemie, przesyłanie do VOID było w rzeczywistości wolniejsze. A co powiesz na = $ null? 34217.685ms ..... nadal cholernie wolniej! Tak więc, jak pokazują ostatnie trzy proste testy, wartość Out-Null jest w rzeczywistości SZYBSZA w wielu przypadkach, gdy potok jest już używany.
Więc dlaczego tak się dzieje? Prosty. To jest i zawsze było w 100% halucynacją, że połączenie z Out-Null było wolniejsze. Chodzi jednak o to, że RUROWANIE DO WSZYSTKIEGO jest wolniejsze i czy nie wiedzieliśmy już o tym za pomocą podstawowej logiki? Po prostu możemy nie wiedzieć, JAK DUŻO wolniej, ale te testy z pewnością opowiadają historię o koszcie korzystania z potoku, jeśli można go uniknąć. I nie myliliśmy się w 100%, ponieważ istnieje bardzo MAŁA liczba prawdziwych scenariuszy, w których wartość zerowa jest zła. Kiedy? Podczas dodawania Out-Null dodaje się TYLKO działanie potoku. Innymi słowy… powodem jest proste polecenie, takie jak $ (1..1000) | Out-Null, jak pokazano powyżej, okazało się prawdą.
Jeśli po prostu dodasz dodatkową potokę do Out-String do każdego powyższego testu, #s zmieniają się radykalnie (lub po prostu wklejasz te poniżej) i, jak sam widzisz, Out-Null faktycznie staje się SZYBSZY w wielu przypadkach:
źródło
Out-Null
potoku, więc najlepszym sposobem pokazania narzutu potoku jest wywołanieOut-Null
z nim i bez niego. W moim systemie przy 10000 iteracji otrzymuję 0,576 sekundy wOut-Null -InputObject $GetProcess
porównaniu z 5,656 sekundy (prawie 10 razy wolniej)$GetProcess | Out-Null
.[void]
i$null
nadal osiągałem lepsze niż| Out-Null
. Rozumiem, żeOut-Null
dzieje się tak z powodu rurociągu i delta kurczy się wraz z późniejszymi partiami, ale na moim komputerze nie działa szybciej w żadnej z partii.[void]
i$null
będzie działać lepiej niż| Out-Null
- dzięki|
. SpróbujOut-Null -InputObject (expression)
dla porównania.Istnieje również
Out-Null
cmdlet, którego można użyć na przykład w potokuAdd-Item | Out-Null
.Strona podręcznika dla Out-Null
źródło
[void]
mimo że rozwiązanie Out-Null wygląda bardziej „powershellish”.[void]
wygląda bardzo przejrzyście (choć nie jest w Powerhellish, jak powiedziałem), zobaczysz na początku wiersza, że nie ma wyjścia w tym wierszu. Więc to jest kolejna zaleta, a jeśli zrobisz Out-Null w dużej pętli, wydajność może być problemem;)Rozważałbym użycie czegoś takiego:
Dane wyjściowe z
$a.Add
nie są zwracane - dotyczy to wszystkich$a.Add
wywołań metod. W przeciwnym razie musiałbyś poprzedzać[void]
przed każdym połączeniem .W prostych przypadkach wybrałbym,
[void]$a.Add
ponieważ jest całkiem jasne, że wynik nie zostanie wykorzystany i zostanie odrzucony.źródło
Osobiście używam,
... | Out-Null
ponieważ, jak zauważyli inni, wygląda to na bardziej "PowerShellish" podejście w porównaniu z... > $null
i[void] ...
.$null = ...
wykorzystuje określoną automatyczną zmienną i można ją łatwo przeoczyć, podczas gdy inne metody za pomocą dodatkowej składni jasno pokazują, że zamierzasz odrzucić dane wyjściowe wyrażenia. Ponieważ... | Out-Null
i... > $null
na końcu wyrażenia, myślę, że skutecznie komunikują się "weź wszystko, co zrobiliśmy do tego momentu i wyrzuć to", a ponadto możesz je łatwiej komentować w celach debugowania (np.... # | Out-Null
), W porównaniu do wstawiania$null =
lub[void]
wcześniej wyrażenie określające, co dzieje się po jego wykonaniu.Spójrzmy jednak na inny test porównawczy: nie ilość czasu potrzebnego do wykonania każdej opcji, ale czas potrzebny na ustalenie , co robi każda opcja . Pracując w środowiskach z kolegami, którzy nie mieli doświadczenia z PowerShell, a nawet w ogóle nie pisali skryptów, staram się pisać moje skrypty w taki sposób, że ktoś, kto pojawi się po latach i może nawet nie rozumieć języka, na który patrzy, może mieć walcząc z szansą na ustalenie, co robi, ponieważ mogą być w sytuacji, gdy będą musieli go wspierać lub zastępować. Nigdy nie przyszło mi to do głowy jako powód, by do tej pory używać jednej metody zamiast innych, ale wyobraź sobie, że jesteś w takiej sytuacji i używasz
help
polecenia lub ulubionej wyszukiwarki, aby dowiedzieć się, coOut-Null
robi. Natychmiast uzyskasz użyteczny wynik, prawda? Teraz spróbuj zrobić to samo z[void]
i$null =
. Nie takie proste, prawda?To prawda, pomijanie wartości wyjściowej jest dość drobnym szczegółem w porównaniu do zrozumienia ogólnej logiki skryptu, a możesz tylko próbować „ogłupić” swój kod tak bardzo, zanim zamienisz umiejętność napisania dobrego kodu na umiejętność czytania ... niezbyt dobrego kodu przez nowicjusza. Chodzi mi o to, że to możliwe, że tacy, którzy biegle w PowerShell nawet nie zna
[void]
,$null =
itd, i właśnie dlatego te może wykonać szybciej lub wziąć mniej klawiszy do typu, nie oznacza, że są najlepszym sposobem aby to zrobić co próbujesz zrobić, a tylko dlatego, że język ma dziwaczną składnię, nie oznacza, że powinieneś go używać zamiast czegoś jaśniejszego i lepiej znanego. ** Przypuszczam, że
Out-Null
jest to jasne i dobrze znane, czego nie wiem$true
. Niezależnie od opcji, możesz czuć się najczystsze i najbardziej dostępne dla czytelników i redaktorów kodzie przyszłych (siebie w zestawie), niezależnie od czasu do rodzaju i czasu do wykonania, to opcja ja polecając skorzystać.źródło