Как работает O = Deparse, и есть ли в Perl и сворачивать константы? - PullRequest
8 голосов
/ 25 августа 2010

Мне интересно, -MO=Deparse показывает вам все оптимизации Perl, и почему это не сворачивается в Perl 5.10?

$ perl -MO=Deparse -e'[qw/foo bar baz/]->[0]'
['foo', 'bar', 'baz']->[0];
-e syntax OK

Некоторые в IRC думали, что O=Deparse можетне показывать все это, но это, безусловно, показывает некоторое постоянное свертывание.

$ perl -MO=Deparse -e'use constant "foo" => "bar"; foo'
use constant ('foo', 'bar');
'???';
-e syntax OK

Тот же результат, если я явно напишу константу sub.Несмотря на предсказуемость, также довольно интересно, что в документации в constant.pm вы создаете список констант , а не константный массив .Я предполагаю, что не только это не свернуто как скалярные константы, но и требует дополнительных затрат на создание нового массива при каждом вызове.

$ perl -MO=Deparse -e'use constant foo => qw/foo bar baz/; (foo)[0]'
use constant ('foo', ('foo', 'bar', 'baz'));
(foo)[0];
-e syntax OK

Единственный вывод, к которому я могу прийти, это -MO=Deparse показываетсворачивания, а постоянные массивы просто не оптимизированы в Perl?Это так?Есть ли техническая причина для этого?

Ответы [ 2 ]

9 голосов
/ 25 августа 2010

Вы не можете создавать постоянные массивы, потому что массивы не являются данными. Perl 5 имеет пять типов данных (вещи, которые можно хранить в переменных):

  • нет значения (undef)
  • номер
  • строка
  • ссылки
  • списки (составленные из одного или нескольких предыдущих типов)

Вы можете сделать константу из любого из них. В Perl 5 также есть три контейнера:

  • Скалярное
  • Массив
  • Hash

Скаляры могут содержать любой из первых четырех типов данных, массивы и хэши могут содержать списки. Важно не путать вещи, которые содержат данные, и сами данные.

Что касается B::Deparse, он сбрасывает optree после его построения, поэтому он покажет результаты всего постоянного свертывания.

Я еще недостаточно об этом думал, но не вижу очевидных причин, по которым его нельзя сложить.

8 голосов
/ 25 августа 2010

Вы не можете создать константный массив в Perl, во внутренних органах нет ничего, что указывало бы на константный массив, хеш или даже скаляр.«use constant» использует способность Perl встроить подпрограммы с прототипом () и простым кодом.Лучшее, что вы можете сделать, это установить флаг readonly , но его можно отключить во время выполнения.

Perl может использовать флаг readonly во время компиляции в качестве подсказки, чтобы указать, что массив действительнотолько для чтения, а затем встроить любой доступ, используя постоянный индекс.Такая эвристика, вероятно, была бы безопасной, поскольку флаг readonly не должен быть доступен пользователю, и вам, вероятно, не следует его сбрасывать.

...