Влияют ли комментарии на производительность Perl?
Я оптимизирую некоторые часто запускаемый код Perl (один раз в день для каждого файла).
Замедляют ли комментарии скрипты на Perl? Мои эксперименты склоняются к нет:
use Benchmark;
timethese(20000000, {
'comments' => '$b=1;
# comment ... (100 times)
', 'nocomments' => '$b=1;'});
Дает практически одинаковые значения (кроме шума).
Benchmark: timing 10000000 iterations of comments, nocomments...
comments: 1 wallclock secs ( 0.53 usr + 0.00 sys = 0.53 CPU) @ 18832391.71/s (n=10000000)
nocomments: 0 wallclock secs ( 0.44 usr + 0.00 sys = 0.44 CPU) @ 22935779.82/s (n=10000000)
Benchmark: timing 20000000 iterations of comments, nocomments...
comments: 0 wallclock secs ( 0.86 usr + -0.01 sys = 0.84 CPU) @ 23696682.46/s (n=20000000)
nocomments: 1 wallclock secs ( 0.90 usr + 0.00 sys = 0.90 CPU) @ 22099447.51/s (n=20000000)
Я получаю аналогичные результаты, если запускаю комментарии и версии без комментариев как отдельные сценарии Perl.
Это кажется нелогичным, если интерпретатору не нужно ничего читать в память каждый раз.
9 ответов
Perl - это язык, скомпилированный как раз вовремя, поэтому комментарии и POD не влияют на производительность во время выполнения.
Комментарии и POD оказывают незначительное влияние на время компиляции, но они так легко и быстро анализируются Perl, что практически невозможно измерить снижение производительности. Вы можете убедиться в этом сами, используя -c
флаг, чтобы просто скомпилировать.
На моем Macbook Perl-программа с 2 операторами и 1000 строками комментариев по 70 символов занимает столько же времени, что и программа с 1000 строками пустых комментариев, как одна с двумя операторами печати. Обязательно запустите каждый бенчмарк дважды, чтобы позволить вашей ОС кешировать файл, иначе вы сравните время чтения файла с диска.
Если время запуска является проблемой для вас, это не из-за комментариев и POD.
Производительность во время выполнения? Нет.
Разбор и лексирование производительности? Да, конечно.
Так как Perl имеет тенденцию анализировать и lex на лету, то комментарии будут влиять на производительность при запуске.
Будут ли они заметно влиять на это? Навряд ли.
Perl компилирует скрипт и затем выполняет его. Комментарии незначительно замедляют фазу компиляции, но не влияют на фазу запуска.
Perl не является языком сценариев в том же смысле, что и сценарии оболочки. Интерпретатор не читает файл построчно. Выполнение Perl-программы выполняется в два основных этапа: компиляция и время выполнения [1]. На этапе компиляции исходный код анализируется и преобразуется в байт-код. На этапе выполнения байт-код выполняется на виртуальной машине.
Комментарии замедляют этап разбора, но разница незначительна по сравнению со временем, необходимым для разбора самого скрипта (который уже очень мал для большинства программ). Единственный раз, когда вас действительно волнует время разбора, это среда веб-сервера, где программа может вызываться много раз в секунду. mod_perl существует для решения этой проблемы.
Вы используете Benchmark
, Это хорошо! Вы должны искать способы улучшить алгоритм, а не микрооптимизацию. Devel::DProf может быть полезен для поиска горячих точек. Вы абсолютно не должны удалять комментарии в ошибочной попытке сделать вашу программу быстрее. Вы просто сделаете это неуправляемым.
[1] Обычно это называется сборкой "как раз вовремя". Perl на самом деле имеет еще несколько этапов, таких как INIT
а также END
это не имеет значения здесь.
Дело в том, чтобы оптимизировать узкие места. Чтение в файле состоит из:
- открыв файл,
- читая его содержание,
- закрытие файла,
- Разбор содержимого.
Из этих шагов чтение - самая быстрая часть (я не уверен насчет закрытия, это системный вызов, но вам не нужно ждать, пока он закончится). Даже если это 10% от всего (что, я думаю, не так), то уменьшение его вдвое дает только 5% улучшенную производительность за счет отсутствия комментариев (что очень плохо). Для синтаксического анализатора удаление строки, начинающейся с #, не является ощутимым замедлением. И после этого комментарии исчезли, поэтому не может быть никакого замедления.
Теперь представьте, что вы могли бы на самом деле улучшить часть "чтение в сценарии" на 5%, убрав все комментарии (что является действительно оптимистичной оценкой, см. Выше). Насколько велика доля "чтения в сценарии" в общем времени выполнения сценария? Конечно, зависит от того, сколько он делает, но поскольку perl-скрипты обычно читают как минимум еще один файл, это максимум 50%, но, поскольку perl-скрипты обычно делают что-то большее, честная оценка снизит это до некоторого диапазона. 1%. Таким образом, ожидаемое повышение эффективности за счет удаления всех комментариев составляет максимум (очень оптимистично) 2,5%, но на самом деле ближе к 0,05%. И потом, те, которые на самом деле дают более 1%, уже работают быстро, так как они почти ничего не делают, так что вы снова оптимизируете не в ту точку.
В заключение, оптимизировать узкие места.
Модуль Benchmark в этом случае бесполезен. Он только измеряет время выполнения кода снова и снова. Поскольку ваш код на самом деле ничего не делает, большая часть его оптимизируется. Вот почему вы видите, что это работает 22 миллиона раз в секунду.
У меня есть почти на всю главу об этом в освоении Perl. Погрешность измерения в методике Benchmark составляет около 7%. Ваши показатели соответствуют этому, так что разницы практически нет.
От Пола Томблинса комментарий:
Разве Perl не выполняет компиляцию на лету? Может быть, комментарии отбрасывают рано? -
Да, Perl делает.
Это язык программирования между скомпилированным и интерпретированным. Код компилируется на лету, а затем запускается. комментарии обычно не имеют никакого значения. Максимум, на что это, вероятно, повлияет, - это то, что когда он изначально разбирает файл построчно и предварительно компилирует его, вы можете увидеть нано-вторую разницу.
Я ожидаю, что один комментарий будет проанализирован только один раз, а не несколько раз в цикле, поэтому я сомневаюсь, что это действительный тест.
Я ожидал бы, что комментарии будут немного замедлять компиляцию, но я ожидаю, что это будет слишком незначительным, чтобы беспокоить их удаление.
Замедляют ли комментарии Perl сценарий? Ну, разбор, да. Выполнение после анализа? Нет. Как часто анализируется скрипт? Только один раз, так что если у вас есть комментарий в цикле for, то комментарий отбрасывается при разборе один раз, до того, как сценарий даже запустится, как только он запустится, комментарий уже пропущен (и сценарий не сохраняется внутри скрипта как Perl), поэтому независимо от того, сколько раз повторяется цикл for, комментарий не будет влиять. Как быстро парсер может пропустить комментарии? То, как пишутся комментарии на Perl, очень быстро, поэтому я сомневаюсь, что вы заметите. Вы заметите более высокое время запуска, если у вас есть 5 строк кода и между каждой строкой 1 миллион строк комментариев... но насколько вероятно, и с какой пользой будет такой большой комментарий?