Рассмотрим идеальный случай, когда сценарий был написан с
use strict;
use warnings FATAL => 'all';
И тщательно проверены, протестированы и отлажены, и вы довольны тем, как это работает.
В скрипте нет динамически генерируемого кода или других причудливых вещей, а код в целом простой и низкотехнологичный.
Для критичных приложений такой скрипт будет таким же корректным и безопасным с закомментированными проверками:
# use strict;
# use warnings FATAL => 'all';
Как с ними дальше?
При условии соблюдения особой осторожности во время редактирования, обновления и любого другого обслуживания, чтобы повторно включить как use strict, так и use warnings и повторно протестировать.
ИМХО, на правильность вопроса стоит ответить, независимо от того, оправдывает ли первоначальная причина хлопот по мнению читателя. Ответы типа «вы должны использовать это, потому что вы не много теряете» или «вы просто должны использовать это, потому что это лучшая практика» не являются ответами. Давайте по-новому и непредвзято посмотрим, действительно ли strict и warnings, несомненно, рекомендуется оставлять в уже отлаженном скрипте.
Причина заключается в штрафах за время выполнения задачи, которые вводят эти прагмы.
Для скрипта, который делает свою работу быстро, вызывается много раз и имеет значительное время отклика — кумулятивный эффект может иметь значение.
Процессор i5-3320M, ОС OpenBSD 7.2 amd64.
for i in $(seq 3); do
time for i in $(seq 10000); do
/usr/bin/perl -e ';'
done
sleep 3
done
sleep 3
for i in $(seq 3); do
time for i in $(seq 10000); do
/usr/bin/perl -e 'use strict; use warnings;'
done
sleep 3
done
Perl версии 5.32.1, исправлен поставщиком для обеспечения безопасности (читай, для снижения производительности). 3 прохода по 10000 /usr/bin/perl -e ';':
1m32.01s real 0m00.60s user 0m03.24s system
1m32.60s real 0m00.70s user 0m03.42s system
1m31.53s real 0m00.69s user 0m04.17s system
3 прохода по 10000 /usr/bin/perl -e 'use strict; use warnings;':
2m46.08s real 0m00.72s user 0m04.63s system
2m48.99s real 0m00.61s user 0m04.79s system
2m49.64s real 0m00.75s user 0m05.16s system
Разница во времени секундомера примерно 75 секунд для 10000 вызовов.
Та же команда оболочки, но perlbrew-установленная /opt/p5/perlbrew/perls/perl-5.36.0/bin/perl вместо поставщика /usr/bin/perl: 3 прохода по 10000 /opt/p5/perlbrew/perls/perl-5.36.0/bin/perl -e ';':
1m09.31s real 0m00.48s user 0m02.60s system
1m12.06s real 0m00.49s user 0m02.94s system
1m14.81s real 0m00.70s user 0m03.44s system
3 прохода по 10000 /opt/p5/perlbrew/perls/perl-5.36.0/bin/perl -e 'use strict; use warnings;':
2m20.81s real 0m00.55s user 0m04.03s system
2m21.98s real 0m00.72s user 0m04.26s system
2m21.75s real 0m00.58s user 0m03.86s system
Разница во времени секундомера примерно 70 секунд для 10000 вызовов.
Для тех, кому время кажется слишком долгим, это из-за OpenBSD. Я провел некоторые замеры, и perl «hello world» оказался 8,150 / 1,688 = в 4,8 раза медленнее на OpenBSD, чем на antiX Linux
/usr/bin/perl -e 'use strict;':
1m59.70s real 0m00.51s user 0m04.27s system
1m59.36s real 0m00.58s user 0m04.04s system
1m57.58s real 0m00.63s user 0m04.50s system
Приблизительно 26 секунд секундомера накладные расходы на 10000 вызовов.
/opt/p5/perlbrew/perls/perl-5.36.0/bin/perl -e 'use strict;':
1m29.06s real 0m00.59s user 0m04.55s system
1m30.04s real 0m00.52s user 0m04.57s system
1m31.26s real 0m00.54s user 0m05.30s system
Приблизительно 20 секунд времени секундомера накладные расходы на 10000 вызовов.
До сих пор ответы были в основном уклончивыми, указывая на незначительность штрафов за производительность. Можно или не заботиться о 7 миллисекундах на вызов или 70 секундах на 10K вызовов. Что бы ни. Пожалуйста, не обращайте внимания на указанную причину или любую другую возможную причину и сосредоточьтесь на фактическом вопросе о правильности, поскольку он сам заслуживает четкого ответа.
Я был бы очень удивлен, если бы use strict; use warnings; ввели какие-либо заметные штрафы за производительность. За исключением, возможно, если у вас есть программа, которая выдает чрезмерное количество предупреждений. strict должна быть в основном производительность во время компиляции.
«Я не всегда отключаю функции безопасности, но когда я это делаю, они уже в работе».
7 мс - это потеря производительности? Возможно, вам следует попробовать этот тест с каким-нибудь реальным кодом в программе, процент штрафа должен быть очень маленьким.
@TLP не 7 мс, а 70 секунд, то есть более минуты, для 10 000 вызовов, а одна только strict занимает 20 или 26 секунд для 10 000 вызовов.
@uxer 70s/10000 = 7 мс на итерацию. Если вы запустите это в программе, выполнение которой занимает 1 секунду, 10 000 вызовов займут почти 3 часа, а снижение производительности strict и warnings составит 70 секунд из них. Это очень мало. Есть много вещей, которые вы можете сделать с программой, чтобы оптимизировать ее, и это намного эффективнее, чем это.
@uxer Спасибо, но вы синхронизируете это с компиляцией в программе, которая ничего не делает. (Попробуйте также загрузить, скажем, DateTime, чтобы увидеть, как увеличивается общее время.) Хотя время компиляции может иметь значение, я не думаю, что это то, что вы имели в виду под производительностью в вопросе. Кроме того, есть небольшая случайность при выходе из такой оболочки.
@uxer Почему бы не попробовать программу, которая занимает, скажем, 5-10 секунд, и многократно запускать ее со строгими / предупреждениями и без них.
@zdim Слово «производительность» было ошибкой, назовем это «время закончить задачу». Многократный запуск недолговечного скрипта, и время отклика должно быть низким. Опять же, мы можем обсуждать сроки, но на самом деле вопрос не в этом. Кажется, слово "безопасность" тоже было ошибкой, назовем это корректностью.
@tadman «Я не всегда отключаю функции безопасности, но когда я это делаю, это работает». :D Это похоже на (не очень) секретный девиз последних разработок в области здравоохранения, пищевой промышленности, беспроводных технологий, компьютерных систем и других современных событий. Приятно знать, что эта тенденция не одобряется на этой веб-странице. Я надеюсь, что эта немилость вернется в другие области деятельности, где она в настоящее время находится в упадке.
@uxer Правильно ли удалять строгие правила и предупреждения? Нет. Если вы закончили отладку, они все равно будут молчать. Любые новые проблемы, возникающие из-за измененного ввода, структуры файлов, обновлений программного обеспечения, будут обнаружены, только если они все еще присутствуют. Если пользы от их удаления нет, то удалять их неправильно.
@uxer «Опять же, мы можем обсуждать сроки, но на самом деле вопрос не в этом». -- Конечно, и вкратце: нельзя отключить предупреждения. Это может оставить вас в дураках. Даже «идеальные» тесты (что это?) не могут охватить все возможности, а лучшие из них, которые мы действительно можем иметь для производства, определенно не учитывают некоторые ситуации. (Потому что вы должны, особенно те, которые крайне маловероятны, хотя и не поставят под угрозу общую работу.) И затем они могут произойти через шесть месяцев после того, как вы отключили предупреждения. Ты никогда даже не узнаешь. Ну, а тогда какая разница, скажете вы...
@uxer ... Что ж, как только мы вернемся в реальную жизнь, время начнет иметь значение: вы ничего не сохраняете, пропуская предупреждения. И я буквально ничего не имею в виду: Рассмотрим два случая: 1) скрипт занимает некоторое время. Тогда время последовательных запусков, вероятно, будет различаться больше, чем требуется для компиляции предупреждений 2) программа делает очень мало, но должна быть быстрой - гм, нет: если эти миллисекунды запуска имеют значение, то это не должен быть Perl. Это должен быть компилируемый язык.
@uxer Вот пара примеров. При запуске сложной программы у NFS произошел сбой (слишком медленный?), и вскоре после записи файла он вела себя так, как будто файла не было (это было - я не шучу!), поэтому программа пошла по другому пути, что позже привело к путанице, потому что исходный файл был там. Были даже явные тесты, и NFS все еще обманывала меня. Откуда мне знать? Потому что не было зарегистрировано никаких предупреждений, которые в противном случае, в этом конкретном случае, были бы там. Это был единственный подобный случай за годы ежедневных запусков (хотя были и другие загадочные сбои NFS).
@uxer Другой случай - однажды меня спросили именно о том, что вы сейчас поднимаете, обрезать конкретную программу, чтобы ее можно было вызывать очень часто, поэтому будьте очень дешевы. (Они отказались от моего совета и предложили затем переписать его на C, да.) Короче говоря, лучшее, что я мог сделать, это запустить несколько сотен миллисекунд (думаю, модули не остались). Мне даже в голову не пришло прикоснуться к warnings/strict.
(Я не хочу монополизировать это пространство, поэтому дайте мне знать, как только вы увидите эти комментарии, и я их удалю.)
«До сих пор ответы в основном уклончивые ...» - я только что заметил это в обновлении вопроса ... Здесь нет ничего уклончивого (??), поскольку несколько человек прямо говорят вам не отключать предупреждения. Там даже есть полный ответ на этот счет. Что еще вы ожидаете? (Конечно, вы можете, если вы хорошо протестировали, но тогда вы все равно можете получить сюрприз, и все.)
@zdim Это место для обсуждения, поэтому я бы посоветовал оставить ваши комментарии, а не удалять их. Однако они ваши, так что делайте, как хотите.
Re "Это место для обсуждения", Абсолютно нет. Комментарии совершенно явно НЕ для обсуждения. Обсуждения можно вести в чате.
Прежде всего, ни одна из прагм не приводит к снижению производительности. Они просто устанавливают флаги, которые проверяются только при возникновении исключительных ситуаций, и проверяются, использовались ли прагмы или нет. Таким образом, весь вопрос основан на ложной предпосылке.
Но чтобы ответить на ваш вопрос, обе эти прагмы имеют эффект времени выполнения, поэтому, будет ли их удаление иметь значение, зависит от тщательности ваших тестов. Вероятно, они не полные, так что разница возможна, даже вероятна.
«обе эти прагмы имеют эффект времени выполнения», «разница возможна, даже вероятна» — пожалуйста, уточните, имели ли вы в виду производительность или эффект безопасности или и то, и другое. Я читал, что вы говорите о безопасности, поэтому влияние на безопасность и разницу в безопасности из-за неполноты тестов. Верно? И штраф за производительность не вводится. Верно? Я получил разницу в 70 секунд для 10000 вызовов. Пожалуйста, взгляните на мой обновленный вопрос. Для тестов давайте рассмотрим идеальный академический сценарий полного охвата. Будет ли разница?
@uxer Полное тестовое покрытие не означает, что испробованы все возможные пути. Могут быть обстоятельства, которые не происходят во время тестирования - удаление файла, как я упоминаю в комментарии, - что приводит к непредвиденному запуску. Что касается ваших тестов - они измеряют компиляцию, и я не думаю, что это имелось в виду под "производительностью" в вопросе.
Re «Кто-то может или не может заботиться о [...] 70 секундах для 10K вызовов». Если вас это волнует, решение не удаляет use strict; use warnings;; это использовать один вызов для выполнения этих 10 000 запросов. Затем 70 с становятся 7 мс, и все это без удаления use strict; use warnings;. И это всего лишь крошечная крошечная часть времени, которое вы бы сэкономили. Итак, как я уже сказал, ни одна из прагм не вводит никаких наказаний. Ваши тесты не показывают обратного.
Re «пожалуйста, уточните, имели ли вы в виду производительность или эффект безопасности или и то, и другое». Я очень четко сказал, что их использование не снижает производительность. И «безопасность» — это не то, что делают прагмы. (Это даже не глагол!) Эффект от их использования вызывает исключение. Поэтому альтернативой было бы не генерировать исключение.
«ни одна прагма не вводит никаких штрафов. Ваши тесты не показывают обратного» — они показывают штрафы за запуск. Слово "спектакль" было моей ошибкой. «Я очень четко сказал, что их использование не влияет на производительность», — вы это сделали. Тем не менее, во втором абзаце вы сказали, что они имеют «эффект», не указав характер эффекта, что не способствует ясности. «Безопасность» — моя ошибка, называя это так. Подойдет ли слово "правильность"? Я склонен думать, что вы уловили смысл. Если я использую неправильные формулировки, я делаю это не намеренно. «даже не глагол» — к чему это относится?
«Если вас это волнует, решение не удаляет use strict; use warnings;, а использует один вызов для выполнения этих 10 000 запросов». — разумное практическое предложение. Я подумаю, TY. Теперь, пожалуйста, давайте не будем подчеркивать тайминги, так как первоначальной целью было узнать о правильности. Вы сказали о неполноте тестов. Я ценю это. Если есть что добавить, буду рад прочитать об этом. А если это все, то это все
Я имел в виду, что «ни у кого» никогда не было полных тестов. И что важно здесь, так это самые необычные обстоятельства, которые, скорее всего, отсутствуют в наборе тестов.
Re "к чему это относится?", Безопасность.
Re «Подойдет ли слово «правильность»?» Нет, исключения — это то, что они делают. Они не безопасны. Они не правы. Эти фразы даже не имеют смысла.
Что касается «они показывают штрафы за запуск», то нет. В худшем случае это дополнительная 1 мс каждые несколько минут. Это меньше, чем шум. Это не пенальти.
@ikegami Слово «производительность» — нет, слово «безопасность» — нет, слово «правильность» — нет. Я видимо плохо подбираю термины. Ваши ответы были бы более конструктивными, если бы они предлагали более подходящие названия для обсуждаемых вещей. Чтобы мы могли переключиться на предложения, которые имеют смысл
@ikegami "Это даже не глагол!" - что оно относится к? - "Безопасность". "Они не безопасность. Они не правильность". Извините, а поясните непосвященному, почему должен быть глагол?
@ikegami «В худшем случае это дополнительная 1 мс каждые несколько минут. Это меньше, чем шум. Это не штраф» — интересно, как вы делаете эти расчеты и получаете 1 мс каждые несколько минут.
Re «Ваши ответы были бы более конструктивными, если бы они предлагали лучшие имена», я так и сделал. Дважды. В третий раз они делают "Выдает исключения". "Оповещает пользователя о проблемах" тоже работает.
Re «Интересно, как вы выполняете эти вычисления и получаете 1 мс каждые несколько минут». Либо вы запускаете программу только изредка, либо у вас есть постоянные запросы, и вы пишете программу, которая обрабатывает несколько запросов. В любом случае время загрузки программы не имеет значения. Мы уже покрыли это до смерти. О, и это 1 мс, а не 7 мс на моем рабочем столе.
Скажем, вы запускаете программу 10 тысяч раз подряд. Вы спрашиваете, можно ли скрыть ошибки, чтобы сэкономить 1 * 9999 мс, когда правильное исправление программы (загрузка ее только один раз) сэкономит вам 500 * 9999 или больше всего только за время компиляции, не говоря уже о времени подключения к базе данных, время синтаксического анализа конфигурации и т. д., и т. д., и т. д. Заставить вашу программу работать в 1000 раз быстрее без необходимости скрывать ошибки намного лучше, чем сделать ее в 1 * 9999 быстрее и скрыть ошибки! Вам сказали это кристально ясно, но вы продолжаете задавать одни и те же вопросы.
Strict и warnings — инструменты разработчика. Если вы закончили разработку и все чисто, они вам больше не нужны. Обратите внимание на то, что @ikegami уже сказал.
В определенных средах, где регистрируются все стандартные ошибки, у вас есть вероятность того, что какой-то новый perl, измененная настройка или непроверенный путь кода будут выдавать предупреждения. У меня была одна ситуация в моей карьере, когда ранее чистый скрипт начал выдавать тонны предупреждений после обновления perl. Это в конечном итоге заполнило диск и отключило службу. Это было не весело. Если никто не следит за предупреждениями, бессмысленно их выдавать. Но урок здесь заключается в правильном мониторинге.
Я не думаю, что предупреждения должны быть включены в производственном коде, потому что вы должны были либо исправить их, либо решили их игнорировать. Иногда, но редко, я отключаю предупреждения в очень небольшой области, потому что исправление затруднит чтение кода или вызовет другие проблемы:
{
no warnings qw(uninitialized);
....
}
Но на самом деле я обычно просто исправляю предупреждения и оставляю их включенными. Я перестал заботиться о Perl v5.12, который бесплатно включает предупреждения:
use v5.12; # free warnings
Меня больше волнует указание минимальной версии Perl, чем удаление строки use warnings или добавление строки no warnings.
И с v5.36 я получаю критические замечания, когда указываю это как минимальную версию:
use v5.36; # free warnings and free strict
Наконец, ваш заявленный штраф составляет 7 мс. Если это горячий путь в вашем коде, вы счастливчик. Если вас беспокоит время запуска и вам нужны эти 7 мс, есть другие вещи, которые вы должны сделать, чтобы восстановить это время запуска.
Но помните, что однократный тест на многопользовательской многопроцессорной машине, даже если вы запустили его на пару секунд, испорчен чем-либо еще. Если вы можете неоднократно показывать задержку в 7 мс при всевозможных нагрузках и ситуациях, то мы должны верить в это. В моем собственном тестировании того же самого на моем MacBook Pro я вижу разницу в целых 30%. Я связываю большую часть этого с тем, что происходит на уровне операционной системы, когда я решаю провести тест.
Что касается «потому что вы должны были их исправить». Если вы их исправили, их включение не требует никаких затрат. Вы оставляете их включенными на случай, если вы не исправили их все.
Re «Я перестал заботиться о Perl v5.12, который включает предупреждения бесплатно:», Это не так. use v5.12; включает строгие, но не предупреждения. use v5.36; также включает предупреждения.
@ikegami - конечно. Вот почему я не должен публиковать, когда я также пытаюсь выбежать за дверь.
Мы никогда не сможем отладить все возможные пути выполнения. Что делать, если файл не открывается из-за того, что пользователь удалил файл? Как насчет неудачных сетевых запросов? Автор программы может даже не знать, что это происходит как часть какой-то другой операции. И т. д. Без предупреждений вы никогда не узнаете, что на самом деле делает программа. (Кроме того, конечно, какой штраф вы измерили? Мне было бы очень любопытно узнать.)