Допустим, у вас есть метод или командлет, который что-то возвращает, но вы не хотите его использовать и не хотите выводить его. Я нашел эти два способа:
Add-Item > $null
[void]Add-Item
Add-Item | Out-Null
Что ты используешь? Какой подход лучше / чище? Зачем?
powershell
null
void
Hinek
источник
источник
Ответы:
Я только что провел несколько тестов четырех известных мне вариантов.
Поэтому я бы посоветовал вам использовать что угодно, но не
Out-Null
из-за накладных расходов. Следующим важным моментом для меня будет удобочитаемость. Мне нравится перенаправляться на себя$null
и становиться равным$null
себе. Я предпочитаю трансляцию[Void]
, но это может быть не так понятно при просмотре кода или для новых пользователей.Думаю, я предпочитаю перенаправлять вывод в
$null
.редактировать
После повторного комментария stej я решил провести еще несколько тестов с конвейерами, чтобы лучше изолировать издержки при выводе.
Вот несколько тестов с простым конвейером из 1000 объектов.
В этом случае
Out-Null
накладные расходы> $null
составляют около 60%, а накладные расходы - около 0,3%.Приложение 2017-10-16: Изначально я упустил из виду еще один вариант
Out-Null
- использование-inputObject
параметра. При этом накладные расходы исчезают, однако синтаксис другой:А теперь несколько тестов с простым конвейером из 100 объектов.
Здесь опять же
Out-Null
около 60% накладных расходов. Пока> $null
имеет накладные расходы около 4%. Числа здесь немного варьировались от теста к тесту (каждый бегал около 5 раз и выбирал середину). Но я думаю, что это показывает явную причину не использоватьOut-Null
.источник
Out-Null
возможно накладные расходы. Но .. если передать один объект наOut-Null
0,076 миллисекунды, imho, он все еще отлично подходит для языка сценариев :)Я понимаю, что это старый поток, но для тех, кто принимает принятый ответ @JasonMArcher выше как факт, я удивлен, что он не был исправлен, многие из нас знали в течение многих лет, что на самом деле ТРУБОПРОВОД добавляет задержку и НИЧЕГО не связано с тем, Это Out-Null или нет. Фактически, если вы запустите приведенные ниже тесты, вы быстро увидите, что те же самые «более быстрые» преобразования в [void] и $ void =, которые мы годами использовали, думая, что это было быстрее, на самом деле ПРОСТО КАК МЕДЛЕННО и на самом деле ОЧЕНЬ МЕДЛЕННО, когда Вы добавляете ЛЮБОЙ конвейер вообще. Другими словами, как только вы переходите к чему-либо, все правило не использовать out-null попадает в корзину.
Доказательство, последние 3 теста в списке ниже. Ужасный Out-null был 32339,3792 миллисекунды, но подождите - насколько быстрее было приведение к [void]? 34121,9251 мс?!? WTF? Это НАСТОЯЩИЕ # в моей системе, преобразование в VOID было на самом деле МЕДЛЕННЫМ. Как насчет = $ null? 34217,685мс ..... еще чертовски МЕДЛЕННО! Итак, как показывают последние три простых теста, Out-Null на самом деле БЫСТРЕЕ во многих случаях, когда конвейер уже используется.
Итак, почему это? Просто. Это и всегда было на 100% галлюцинацией, что передача в Out-Null была медленнее. Тем не менее, ТРУБА К ЧЕМУ-ЛИБО медленнее, и разве мы не знали, что это через базовую логику? Возможно, мы просто не знали НАМНОГО медленнее, но эти тесты наверняка расскажут о стоимости использования конвейера, если вы можете этого избежать. И мы на самом деле не были на 100% неправы, потому что есть очень МАЛЕНЬКОЕ количество истинных сценариев, где out-null - это зло. Когда? При добавлении Out-Null добавляется ТОЛЬКО действие конвейера. Другими словами .... причина в простой команде типа $ (1..1000) | Out-Null, как показано выше, показал истину.
Если вы просто добавите дополнительный канал к Out-String к каждому тесту выше, #s радикально изменятся (или просто вставите те, которые ниже), и, как вы сами можете видеть, Out-Null фактически становится БЫСТРЕЕ во многих случаях:
источник
Out-Null
конвейер вообще, поэтому лучший способ показать издержки конвейера - вызыватьOut-Null
с ним и без него. В моей системе для 10 000 итераций я получаю 0,576 секунды дляOut-Null -InputObject $GetProcess
против 5,656 секунды (почти в 10 раз медленнее) для$GetProcess | Out-Null
.[void]
и по-$null
прежнему выступал лучше, чем| Out-Null
. Я понимаю, что это из-за конвейера, и дельта сокращается с более поздними партиями, но на моей машинеOut-Null
не работает быстрее ни в одной из партий.[void]
и$null
будет работать лучше, чем| Out-Null
- из-за|
. ПопробуйOut-Null -InputObject (expression)
для сравнения.Также существует
Out-Null
командлет, который можно использовать, например, в конвейереAdd-Item | Out-Null
.Страница руководства для Out-Null
источник
[void]
вариант, хотя решение Out-Null выглядит более "мощным".[void]
выглядит очень четко (хотя, как я уже сказал, не PowerShellish), вы увидите в начале строки, что в этой строке нет вывода. Так что это еще одно преимущество, и если вы делаете Out-Null в большом цикле, производительность может быть проблемой;)Я бы подумал об использовании чего-то вроде:
Выходные данные
$a.Add
не возвращаются - это справедливо для всех$a.Add
вызовов методов. В противном случае вам нужно будет добавить[void]
перед каждым вызовом.В простых случаях я бы пошел,
[void]$a.Add
потому что совершенно ясно, что вывод не будет использоваться и будет отброшен.источник
Лично я использую,
... | Out-Null
потому что, как уже отмечали другие, это выглядит как более «PowerShellish» подход по сравнению с... > $null
и[void] ...
.$null = ...
использует определенную автоматическую переменную, и ее можно легко упустить из виду, тогда как другие методы делают очевидным с помощью дополнительного синтаксиса, что вы намереваетесь отбросить вывод выражения. Потому что... | Out-Null
и... > $null
в конце выражения, я думаю, они эффективно сообщают: «возьмите все, что мы сделали до этого момента, и выбросьте это», плюс вы можете комментировать их проще для целей отладки (например... # | Out-Null
), по сравнению с помещением$null =
или[void]
ранее выражение, чтобы определить, что происходит после его выполнения.Давайте рассмотрим другой тест: не количество времени, которое требуется для выполнения каждого параметра, а количество времени, которое требуется для выполнения выяснить, что делает каждый вариант . Работая в среде с коллегами, которые не имели опыта работы с PowerShell или даже с написанием сценариев, я стараюсь писать свои сценарии таким образом, чтобы кто-то, кто придет через несколько лет и даже не поймет язык, на который они смотрят, может иметь шансы выяснить, что он делает, так как они могут поддержать или заменить его. До сих пор это никогда не приходило мне в голову как причина использовать один метод вместо других, но представьте, что вы находитесь в таком положении и используете
help
команду или свою любимую поисковую систему, чтобы попытаться выяснить, чтоOut-Null
делает. Вы сразу получаете полезный результат, верно? Теперь попробуйте сделать то же самое с[void]
и$null =
. Не так просто?Конечно, подавление вывода значения является довольно незначительной деталью по сравнению с пониманием общей логики скрипта, и вы можете только попытаться «замять» код настолько, прежде чем торгуете своей способностью написать хороший код для способность новичка читать ... не очень хороший код. Суть в том, что это возможно , что некоторые , кто владеет PowerShell даже не знакомы с
[void]
,$null =
и т.д., и только потому , что те могут выполняться быстрее или принимать меньше нажатий клавиш типа, не означает , что они лучший способ сделать то, что вы пытаетесь сделать, и то, что язык дает вам необычный синтаксис, не означает, что вы должны использовать его вместо чего-то более ясного и известного. ** Я предполагаю, что
Out-Null
это ясно и хорошо известно, чего я не знаю$true
. Какой бы вариант вы ни считали наиболее ясным и доступным для будущих читателей и редакторов вашего кода (включая вас самих), независимо от времени ввода или выполнения, я рекомендую вам использовать именно этот вариант.источник